diff --git a/AUTHORS b/AUTHORS
index d4f7c9da..1546bf86 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,6 +41,7 @@
 Adrià Vilanova Martínez <me@avm99963.com>
 Ahmed Elwasefi <a.m.elwasefi@gmail.com>
 Ahmet Emir Ercin <ahmetemiremir@gmail.com>
+Aiden Grossman <aidengrossmanpso@gmail.com>
 Ajay Berwal <a.berwal@samsung.com>
 Ajay Berwal <ajay.berwal@samsung.com>
 Ajith Kumar V <ajith.v@samsung.com>
diff --git a/DEPS b/DEPS
index 93ff8cb4..c6cc44e 100644
--- a/DEPS
+++ b/DEPS
@@ -282,15 +282,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd6149a13d696c2c7d420f1f36032286a6cc5c685',
+  'skia_revision': 'f7cb3865a2ed4aac5ced9ba5568c479f60dca7fb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '63ef407d125546fff116adc46842c79f79ba6ebd',
+  'v8_revision': '6c81e9a6e01c603e3278e7757f53eae81e357aff',
   # 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': '72f9add4ca203d622ea7c776c0d85be7c0f833c2',
+  'angle_revision': '76fa380683ca3b1812cfbd3ef4e7ea768819bc75',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -309,7 +309,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:12.20230504.4.1',
+  'fuchsia_version': 'version:12.20230505.2.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -353,7 +353,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': '6b573b067695d201064c41a50b2da675836743cd',
+  'catapult_revision': 'e2a65ffc7d97a4e31b223c23ea479d21e67eaebb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -369,7 +369,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': 'e0a1a7977610c7f3f44f32f1a8178acd2fc0d0e8',
+  'devtools_frontend_revision': 'a0a42d101187c11abcb5a9f78a84de4ea31dc0f2',
   # 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.
@@ -409,7 +409,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '895d240fbf9ec44dfd8900fa13b0aa2dc6dea880',
+  'dawn_revision': '4204bb3ef11e2ea9d10a7a18f32a4ed69cf870a9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -429,7 +429,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libavif
   # and whatever else without interference from each other.
-  'libavif_revision': '1af8cea3d1b3a05ecbcb0e39d99a7f0183e6ce13',
+  'libavif_revision': 'e81008f2ca09bcecfc37c26203da2dea1896350d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
@@ -769,7 +769,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '707dc02ab2f301996bdc6379b0b23361e9dab1c4',
+    'b7885665feeac33fa1e651131eeb1b4fdfe63627',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -868,7 +868,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': '65dZWPchY1cpu0ES4qQA-Ss7IN8gsrgQ8WiA197yPDAC',
+          'version': 'JumEWF-UOwkbAkypei7k8oUgNtj5mSMODQjhdOxwGwIC',
         },
       ],
       'dep_type': 'cipd',
@@ -879,7 +879,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'bMljXD9PrY-_GeuKu8JHWiS0ptwX0CjmKkQ2W79oOzIC',
+          'version': 'wyLDYtzwxG2mQxMPnpQcdX7M-KxnMqZkj6A88v8obhIC',
         },
       ],
       'dep_type': 'cipd',
@@ -890,7 +890,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'WDjZo7azUetFS0NBXgybivAjtj8w7PagYXBTUrTjFDwC',
+          'version': 'Ld4rlDthYnmpNnaNYbENdjQS9pfJFJJqxhsi9326cnoC',
         },
       ],
       'dep_type': 'cipd',
@@ -1161,7 +1161,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c9dec0a8ab8f236b055ff2fbe270b55f9748a103',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '99047eed72ba284c25761dbe376ef95284c5cb6a',
       'condition': 'checkout_chromeos',
   },
 
@@ -1193,13 +1193,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '71ab1b77a7d24991eadf90c3a412f2ffaceccc9f',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'bcb9577a46b3b2c00ebb49e30b3ea9a3fdd3433a',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '9659b46fe81be787d7b3afc798040066281e18ab',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '956d7f61df03b8fc2bdc2a79318fb64c0ee5a9f9',
     'condition': 'checkout_src_internal',
   },
 
@@ -1457,7 +1457,7 @@
     Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd',
 
   'src/third_party/libaom/source/libaom':
-    Var('aomedia_git') + '/aom.git' + '@' +  '5a0903824082f41123e8365b5b99ddb6ced8971c',
+    Var('aomedia_git') + '/aom.git' + '@' +  'b6cfc3cf4551515edd75eb57b77837b58cdba8f4',
 
   'src/third_party/libavif/src':
     Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'),
@@ -1663,7 +1663,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5acf8796c8d042aa5671f87a02369889f3c89c96',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6087bfd57d4cdb4eda85c9b32b73b3b55e48ad87',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1848,7 +1848,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'b83a6ae7088eda73f9d23c81d2e48c0f360eb9e5',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'ab7eb9df02fcbfeb869aba559f5177e247be57dc',
+    Var('webrtc_git') + '/src.git' + '@' + '20a4ec8fa7fdf1618e3720b8e03e9a06a605b212',
 
   # 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.
@@ -1938,7 +1938,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': Var('chrome_git') + '/chrome/src-internal.git@24d200ef8d1f3c3429cddd8b546f9b7e6debde12',
+    'url': Var('chrome_git') + '/chrome/src-internal.git@7f0bfb5898ce5f3049288731e81f59e2607b45f8',
     'condition': 'checkout_src_internal',
   },
 
@@ -1979,7 +1979,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'Zlu7FxtWLj4J802YinUN0DyYeA3e5hx0UYsM49VbVYAC',
+        'version': 'UU7sz8ubtmBEu0TiUfmXmlXBUd7lSloepxGBWdAy3hcC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 733e625..81c8260 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -904,13 +904,6 @@
   if (webview_includes_weblayer) {
     sources += [ "$root_gen_dir/weblayer/weblayer_resources.pak" ]
     deps += [ "//weblayer:resources" ]
-
-    # These resources are primarily useful for developers. To avoid increasing
-    # the size of WebView they are only included in non-stable channels.
-    if (android_channel != "stable") {
-      sources += [ "$root_gen_dir/content/dev_ui_content_resources.pak" ]
-      deps += [ "//content:dev_ui_content_resources" ]
-    }
   }
 }
 
diff --git a/ash/capture_mode/capture_audio_mixing_unittests.cc b/ash/capture_mode/capture_audio_mixing_unittests.cc
index 304ed517d..2e401ed 100644
--- a/ash/capture_mode/capture_audio_mixing_unittests.cc
+++ b/ash/capture_mode/capture_audio_mixing_unittests.cc
@@ -129,4 +129,51 @@
             settings_test_api.GetSystemAndMicrophoneAudioOption());
 }
 
+// -----------------------------------------------------------------------------
+// ProjectorAudioMixingTest:
+
+class ProjectorAudioMixingTest : public CaptureAudioMixingTest {
+ public:
+  ProjectorAudioMixingTest() = default;
+  ~ProjectorAudioMixingTest() override = default;
+
+  // CaptureAudioMixingTest:
+  void SetUp() override {
+    CaptureAudioMixingTest::SetUp();
+    projector_helper_.SetUp();
+  }
+
+  void StartProjectorModeSession() {
+    projector_helper_.StartProjectorModeSession();
+  }
+
+ private:
+  ProjectorCaptureModeIntegrationHelper projector_helper_;
+};
+
+TEST_F(ProjectorAudioMixingTest, AudioSettingsMenu) {
+  StartProjectorModeSession();
+  auto* event_generator = GetEventGenerator();
+
+  // Open the settings menu, and check that only microphone and
+  // system+microphone options are available.
+  ClickOnView(GetSettingsButton(), event_generator);
+
+  CaptureModeSettingsTestApi test_api;
+  views::View* off_option = test_api.GetAudioOffOption();
+  views::View* microphone_option = test_api.GetMicrophoneOption();
+  views::View* system_option = test_api.GetSystemAudioOption();
+  views::View* system_and_microphone_option =
+      test_api.GetSystemAndMicrophoneAudioOption();
+
+  EXPECT_FALSE(off_option);
+  EXPECT_FALSE(system_option);
+  EXPECT_TRUE(microphone_option);
+  EXPECT_TRUE(system_and_microphone_option);
+
+  // Microphone should still be selected by default.
+  EXPECT_TRUE(IsAudioOptionChecked(kAudioMicrophone));
+  EXPECT_FALSE(IsAudioOptionChecked(kAudioSystemAndMicrophone));
+}
+
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_behavior.cc b/ash/capture_mode/capture_mode_behavior.cc
index 38e2917..a74bce6 100644
--- a/ash/capture_mode/capture_mode_behavior.cc
+++ b/ash/capture_mode/capture_mode_behavior.cc
@@ -60,7 +60,17 @@
   bool ShouldSaveToSettingsBeIncluded() const override { return false; }
   bool ShouldGifBeSupported() const override { return false; }
   bool ShouldShowPreviewNotification() const override { return false; }
-  bool IsAudioRecordingRequired() const override { return true; }
+  bool SupportsAudioRecordingMode(AudioRecordingMode mode) const override {
+    switch (mode) {
+      case AudioRecordingMode::kOff:
+      case AudioRecordingMode::kSystem:
+        return false;
+      case AudioRecordingMode::kMicrophone:
+        return true;
+      case AudioRecordingMode::kSystemAndMicrophone:
+        return features::IsCaptureModeAudioMixingEnabled();
+    }
+  }
   bool ShouldCreateRecordingOverlayController() const override { return true; }
   bool ShouldShowUserNudge() const override { return false; }
   bool ShouldAutoSelectFirstCamera() const override { return true; }
@@ -132,8 +142,16 @@
   return true;
 }
 
-bool CaptureModeBehavior::IsAudioRecordingRequired() const {
-  return false;
+bool CaptureModeBehavior::SupportsAudioRecordingMode(
+    AudioRecordingMode mode) const {
+  switch (mode) {
+    case AudioRecordingMode::kOff:
+    case AudioRecordingMode::kMicrophone:
+      return true;
+    case AudioRecordingMode::kSystem:
+    case AudioRecordingMode::kSystemAndMicrophone:
+      return features::IsCaptureModeAudioMixingEnabled();
+  }
 }
 
 bool CaptureModeBehavior::ShouldCameraSelectionSettingsBeIncluded() const {
diff --git a/ash/capture_mode/capture_mode_behavior.h b/ash/capture_mode/capture_mode_behavior.h
index 1235186..d0a0c65 100644
--- a/ash/capture_mode/capture_mode_behavior.h
+++ b/ash/capture_mode/capture_mode_behavior.h
@@ -48,7 +48,8 @@
   virtual bool ShouldFulscreenCaptureSourceBeAllowed() const;
   virtual bool ShouldRegionCaptureSourceBeAllowed() const;
   virtual bool ShouldWindowCaptureSourceBeAllowed() const;
-  virtual bool IsAudioRecordingRequired() const;
+  // Returns true if the given `mode` is supported by this behavior.
+  virtual bool SupportsAudioRecordingMode(AudioRecordingMode mode) const;
   virtual bool ShouldCameraSelectionSettingsBeIncluded() const;
   virtual bool ShouldDemoToolsSettingsBeIncluded() const;
   virtual bool ShouldSaveToSettingsBeIncluded() const;
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc
index 0d266bdf..fe6873e 100644
--- a/ash/capture_mode/capture_mode_controller.cc
+++ b/ash/capture_mode/capture_mode_controller.cc
@@ -1785,8 +1785,8 @@
 
   CaptureModeBehavior* active_behavior =
       capture_mode_session_->active_behavior();
-  if (active_behavior->IsAudioRecordingRequired() &&
-      GetEffectiveAudioRecordingMode() == AudioRecordingMode::kOff) {
+  if (!active_behavior->SupportsAudioRecordingMode(
+          GetEffectiveAudioRecordingMode())) {
     // Before asking the client to create a folder to host the video file, we
     // check if they require audio recording to be enabled, but it can't be
     // allowed due to admin policy. In this case we just abort the recording by
diff --git a/ash/capture_mode/capture_mode_settings_view.cc b/ash/capture_mode/capture_mode_settings_view.cc
index 731dbbc..127ee33 100644
--- a/ash/capture_mode/capture_mode_settings_view.cc
+++ b/ash/capture_mode/capture_mode_settings_view.cc
@@ -79,9 +79,10 @@
     const bool audio_capture_managed_by_policy =
         controller->IsAudioCaptureDisabledByPolicy();
 
-    DCHECK(!audio_capture_managed_by_policy ||
-           !active_behavior->IsAudioRecordingRequired())
-        << "A projector session should not be allowed to begin if audio "
+    DCHECK(
+        !audio_capture_managed_by_policy ||
+        active_behavior->SupportsAudioRecordingMode(AudioRecordingMode::kOff))
+        << "A client session should not be allowed to begin if audio "
            "recording is diabled by policy.";
 
     audio_input_menu_group_ =
@@ -90,37 +91,41 @@
             l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT),
             audio_capture_managed_by_policy));
 
-    if (!active_behavior->IsAudioRecordingRequired()) {
-      // Disallow the user to turn off audio recording if it is required.
-      audio_input_menu_group_->AddOption(
-          /*option_icon=*/nullptr,
-          l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF),
-          kAudioOff);
-    }
+    // A list of all the possible audio options.
+    struct {
+      // The backend audio recording mode for this option.
+      AudioRecordingMode audio_recording_mode;
+      // The ID of this menu group option.
+      int option_id;
+      // The ID of the string that will be used for the option's label.
+      int string_id;
+      // True if the option can be added if audio recording is managed by an
+      // admin policy.
+      bool add_if_managed_by_policy;
+    } kAudioOptions[] = {
+        {AudioRecordingMode::kOff, kAudioOff,
+         IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF,
+         /*add_if_managed_by_policy=*/true},
+        {AudioRecordingMode::kSystem, kAudioSystem,
+         IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_SYSTEM,
+         /*add_if_managed_by_policy=*/false},
+        {AudioRecordingMode::kMicrophone, kAudioMicrophone,
+         IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE,
+         /*add_if_managed_by_policy=*/false},
+        {AudioRecordingMode::kSystemAndMicrophone, kAudioSystemAndMicrophone,
+         IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_SYSTEM_AND_MICROPHONE,
+         /*add_if_managed_by_policy=*/false},
+    };
 
-    if (!audio_capture_managed_by_policy) {
-      const bool audio_mixing_enabled =
-          features::IsCaptureModeAudioMixingEnabled();
-      if (audio_mixing_enabled) {
+    for (const auto& audio_option : kAudioOptions) {
+      if ((!audio_capture_managed_by_policy ||
+           audio_option.add_if_managed_by_policy) &&
+          active_behavior->SupportsAudioRecordingMode(
+              audio_option.audio_recording_mode)) {
         audio_input_menu_group_->AddOption(
             /*option_icon=*/nullptr,
-            l10n_util::GetStringUTF16(
-                IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_SYSTEM),
-            kAudioSystem);
-      }
-
-      audio_input_menu_group_->AddOption(
-          /*option_icon=*/nullptr,
-          l10n_util::GetStringUTF16(
-              IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE),
-          kAudioMicrophone);
-
-      if (audio_mixing_enabled) {
-        audio_input_menu_group_->AddOption(
-            /*option_icon=*/nullptr,
-            l10n_util::GetStringUTF16(
-                IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_SYSTEM_AND_MICROPHONE),
-            kAudioSystemAndMicrophone);
+            l10n_util::GetStringUTF16(audio_option.string_id),
+            audio_option.option_id);
       }
     }
 
@@ -347,7 +352,8 @@
   switch (option_id) {
     case kAudioOff:
       return !audio_capture_managed_by_policy &&
-             !active_behavior_->IsAudioRecordingRequired();
+             active_behavior_->SupportsAudioRecordingMode(
+                 AudioRecordingMode::kOff);
     case kAudioSystem:
     case kAudioMicrophone:
     case kAudioSystemAndMicrophone:
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index 81fc0fe..632dd64 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -4636,7 +4636,10 @@
     EXPECT_TRUE(active_behavior->ShouldFulscreenCaptureSourceBeAllowed());
     EXPECT_TRUE(active_behavior->ShouldRegionCaptureSourceBeAllowed());
     EXPECT_TRUE(active_behavior->ShouldWindowCaptureSourceBeAllowed());
-    EXPECT_FALSE(active_behavior->IsAudioRecordingRequired());
+    EXPECT_TRUE(
+        active_behavior->SupportsAudioRecordingMode(AudioRecordingMode::kOff));
+    EXPECT_TRUE(active_behavior->SupportsAudioRecordingMode(
+        AudioRecordingMode::kMicrophone));
     EXPECT_TRUE(active_behavior->ShouldCameraSelectionSettingsBeIncluded());
     EXPECT_TRUE(active_behavior->ShouldDemoToolsSettingsBeIncluded());
     EXPECT_TRUE(active_behavior->ShouldSaveToSettingsBeIncluded());
@@ -5710,7 +5713,10 @@
         projector_active_behavior->ShouldRegionCaptureSourceBeAllowed());
     EXPECT_TRUE(
         projector_active_behavior->ShouldWindowCaptureSourceBeAllowed());
-    EXPECT_TRUE(projector_active_behavior->IsAudioRecordingRequired());
+    EXPECT_FALSE(projector_active_behavior->SupportsAudioRecordingMode(
+        AudioRecordingMode::kOff));
+    EXPECT_TRUE(projector_active_behavior->SupportsAudioRecordingMode(
+        AudioRecordingMode::kMicrophone));
     EXPECT_TRUE(
         projector_active_behavior->ShouldCameraSelectionSettingsBeIncluded());
     EXPECT_TRUE(projector_active_behavior->ShouldDemoToolsSettingsBeIncluded());
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h
index 01fa03f..a982641c 100644
--- a/ash/public/cpp/wallpaper/wallpaper_controller.h
+++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -43,6 +43,9 @@
 
   using DailyGooglePhotosIdCache = base::HashingLRUCacheSet<uint32_t>;
 
+  using LoadPreviewImageCallback =
+      base::OnceCallback<void(scoped_refptr<base::RefCountedMemory>)>;
+
   WallpaperController();
   virtual ~WallpaperController();
 
@@ -305,9 +308,9 @@
   // Returns the wallpaper image currently being shown.
   virtual gfx::ImageSkia GetWallpaperImage() = 0;
 
-  // Returns the preview image of the currently shown wallpaper. Nullable if the
-  // current wallpaper is not available.
-  virtual scoped_refptr<base::RefCountedMemory> GetPreviewImage() = 0;
+  // Loads the preview image of the currently shown wallpaper. Callback is
+  // called after the operation completes.
+  virtual void LoadPreviewImage(LoadPreviewImageCallback callback) = 0;
 
   // Returns whether the current wallpaper is blurred on lock/login screen.
   virtual bool IsWallpaperBlurredForLockState() const = 0;
diff --git a/ash/rounded_display/rounded_display_frame_factory.cc b/ash/rounded_display/rounded_display_frame_factory.cc
index 51d6eff..5c90baf 100644
--- a/ash/rounded_display/rounded_display_frame_factory.cc
+++ b/ash/rounded_display/rounded_display_frame_factory.cc
@@ -233,17 +233,11 @@
       return nullptr;
     }
 
-    gfx::Transform buffer_to_target_transform;
-
-    // Translate the gutter to correct location in the display.
-    buffer_to_target_transform.Translate(gutter->bounds().x(),
-                                         gutter->bounds().y());
-
     // By applying the inverse of root rotation transform, we ensure that our
     // rounded corner textures are not rotated with the rest of the UI. This
     // also saves us from dealing with having the reverse rotation transform
     // requirements of using hardware overlays.
-    buffer_to_target_transform.PostConcat(root_rotation_inverse);
+    const gfx::Transform& buffer_to_target_transform = root_rotation_inverse;
 
     viz::ResourceId resource_id =
         resource_manager.OfferResource(std::move(resource));
@@ -317,7 +311,7 @@
   // Each gutter can be thought of as a single ui::Layer that produces only one
   // quad. Therefore the layer should be of the same size as the texture
   // produced by the gutter making layer_rect the size of the gutter in pixels.
-  const gfx::Rect layer_rect(gutter.bounds().size());
+  const gfx::Rect& layer_rect = gutter.bounds();
 
   viz::SharedQuadState* quad_state =
       render_pass_out.CreateAndAppendSharedQuadState();
diff --git a/ash/session/fullscreen_controller.cc b/ash/session/fullscreen_controller.cc
index 082152b0..1c431e4 100644
--- a/ash/session/fullscreen_controller.cc
+++ b/ash/session/fullscreen_controller.cc
@@ -17,8 +17,10 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/wm_event.h"
 #include "base/check.h"
+#include "base/strings/string_util.h"
 #include "chromeos/dbus/power_manager/backlight.pb.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
+#include "chromeos/ui/base/window_properties.h"
 #include "chromeos/ui/wm/fullscreen/keep_fullscreen_for_url_checker.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -100,6 +102,20 @@
     return;
   }
 
+  // Do not exit fullscreen for a Borealis window. We do additional checks here
+  // to avoid entering a screen lock with a window which has a not-allowed
+  // property combination. We use CHECKs as those combination should never
+  // happen.
+  if (active_window_state->window()->GetProperty(
+          chromeos::kNoExitFullscreenOnLock)) {
+    CHECK(active_window_state->window()->GetProperty(
+        chromeos::kUseOverviewToExitFullscreen))
+        << "Property combination not allowed. kUseOverviewToExitFullscreen "
+           "must be true if kNoExitFullscreenOnLock is true.";
+    std::move(callback).Run();
+    return;
+  }
+
   if (!keep_fullscreen_checker_) {
     keep_fullscreen_checker_ =
         std::make_unique<chromeos::KeepFullscreenForUrlChecker>(
diff --git a/ash/session/fullscreen_controller_unittest.cc b/ash/session/fullscreen_controller_unittest.cc
index 72a94aa..cc9ef5e 100644
--- a/ash/session/fullscreen_controller_unittest.cc
+++ b/ash/session/fullscreen_controller_unittest.cc
@@ -14,6 +14,7 @@
 #include "ash/wm/window_state.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
+#include "chromeos/ui/base/window_properties.h"
 #include "chromeos/ui/wm/fullscreen/pref_names.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/client/aura_constants.h"
@@ -29,15 +30,15 @@
 constexpr char kMatchingPattern[] = "test.com";
 constexpr char kWildcardPattern[] = "*";
 
-class FullscreenControllerTest : public AshTestBase,
-                                 public testing::WithParamInterface<bool> {
+class FullscreenControllerTestBase : public AshTestBase {
  public:
-  FullscreenControllerTest() {}
+  FullscreenControllerTestBase() = default;
 
-  FullscreenControllerTest(const FullscreenControllerTest&) = delete;
-  FullscreenControllerTest& operator=(const FullscreenControllerTest&) = delete;
+  FullscreenControllerTestBase(const FullscreenControllerTestBase&) = delete;
+  FullscreenControllerTestBase& operator=(const FullscreenControllerTestBase&) =
+      delete;
 
-  ~FullscreenControllerTest() override {}
+  ~FullscreenControllerTestBase() override = default;
 
   // AshTestBase:
   void SetUp() override {
@@ -55,17 +56,17 @@
     AshTestBase::TearDown();
   }
 
+ protected:
   void CreateFullscreenWindow() {
     window_ = CreateTestWindow();
     window_->SetProperty(aura::client::kShowStateKey,
                          ui::SHOW_STATE_FULLSCREEN);
-    if (is_lacros_window_) {
-      window_->SetProperty(aura::client::kAppType,
-                           static_cast<int>(AppType::LACROS));
-    }
+    SetPropertiesForNewFullscreenWindow(window_.get());
     window_state_ = WindowState::Get(window_.get());
   }
 
+  virtual void SetPropertiesForNewFullscreenWindow(aura::Window* window) {}
+
   void SetKeepFullscreenWithoutNotificationAllowList(
       const std::string& pattern) {
     base::Value::List list;
@@ -75,6 +76,21 @@
         std::move(list));
   }
 
+  std::unique_ptr<aura::Window> window_;
+  raw_ptr<WindowState, ExperimentalAsh> window_state_ = nullptr;
+  raw_ptr<TestShellDelegate> test_shell_delegate_ = nullptr;
+};
+
+class FullscreenControllerTest : public FullscreenControllerTestBase,
+                                 public testing::WithParamInterface<bool> {
+ protected:
+  void SetPropertiesForNewFullscreenWindow(aura::Window* window) override {
+    if (is_lacros_window_) {
+      window->SetProperty(aura::client::kAppType,
+                          static_cast<int>(AppType::LACROS));
+    }
+  }
+
   void SetUpShellDelegate(bool should_exit_fullscreen, GURL url = kActiveUrl) {
     // The shell delegate will only retrieve the active URL for ash-chrome
     // windows and return the empty URL for lacros-chrome windows.
@@ -87,14 +103,7 @@
     }
   }
 
- protected:
   bool is_lacros_window_ = GetParam();
-
-  std::unique_ptr<aura::Window> window_;
-
-  raw_ptr<WindowState, ExperimentalAsh> window_state_ = nullptr;
-
-  raw_ptr<TestShellDelegate> test_shell_delegate_ = nullptr;
 };
 
 // Test that full screen is exited after session unlock if the allow list pref
@@ -212,5 +221,42 @@
 
 INSTANTIATE_TEST_SUITE_P(All, FullscreenControllerTest, testing::Bool());
 
+using FullscreenControllerNotLacrosRelatedTest = FullscreenControllerTestBase;
+
+TEST_F(FullscreenControllerNotLacrosRelatedTest,
+       KeepFullscreenIfNoExitPropertySet) {
+  window_->SetProperty(chromeos::kUseOverviewToExitFullscreen, true);
+  window_->SetProperty(chromeos::kNoExitFullscreenOnLock, true);
+  window_->SetProperty(aura::client::kAppType,
+                       static_cast<int>(AppType::CROSTINI_APP));
+
+  ASSERT_TRUE(window_state_->IsFullscreen());
+
+  base::RunLoop run_loop;
+  Shell::Get()->session_controller()->PrepareForLock(run_loop.QuitClosure());
+  GetSessionControllerClient()->LockScreen();
+  EXPECT_TRUE(window_state_->IsFullscreen());
+  GetSessionControllerClient()->UnlockScreen();
+  run_loop.Run();
+  EXPECT_TRUE(window_state_->IsFullscreen());
+}
+
+TEST_F(FullscreenControllerNotLacrosRelatedTest,
+       NoExitPropertyNotAllowedIfOverviewPropertyIsNotSet) {
+  EXPECT_DEATH(
+      {
+        window_->SetProperty(chromeos::kUseOverviewToExitFullscreen, false);
+        window_->SetProperty(chromeos::kNoExitFullscreenOnLock, true);
+
+        ASSERT_TRUE(window_state_->IsFullscreen());
+
+        base::RunLoop run_loop;
+        Shell::Get()->session_controller()->PrepareForLock(
+            run_loop.QuitClosure());
+        GetSessionControllerClient()->LockScreen();
+      },
+      "Property combination not allowed");
+}
+
 }  // namespace
 }  // namespace ash
diff --git a/ash/system/input_device_settings/input_device_settings_policy_handler.cc b/ash/system/input_device_settings/input_device_settings_policy_handler.cc
index fc3fe89..a124c15 100644
--- a/ash/system/input_device_settings/input_device_settings_policy_handler.cc
+++ b/ash/system/input_device_settings/input_device_settings_policy_handler.cc
@@ -51,7 +51,6 @@
 
 void InputDeviceSettingsPolicyHandler::Initialize(PrefService* local_state,
                                                   PrefService* pref_service) {
-  CHECK(local_state);
   if (pref_service) {
     initialized_with_local_state_prefs_ = false;
     pref_change_registrar_.Init(pref_service);
@@ -66,6 +65,7 @@
             &InputDeviceSettingsPolicyHandler::OnKeyboardPoliciesChanged,
             base::Unretained(this)));
   } else {
+    CHECK(local_state);
     initialized_with_local_state_prefs_ = true;
     pref_change_registrar_.Init(local_state);
     pref_change_registrar_.Add(
diff --git a/ash/system/unified/power_button.cc b/ash/system/unified/power_button.cc
index 687ce183..ae68be29 100644
--- a/ash/system/unified/power_button.cc
+++ b/ash/system/unified/power_button.cc
@@ -170,40 +170,6 @@
 
   gfx::FontList font_list_;
 };
-
-// The power button container which contains 2 icons: a power icon and an arrow
-// down icon.
-class PowerButtonContainer : public views::Button {
- public:
-  explicit PowerButtonContainer(PressedCallback callback) : Button(callback) {
-    auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>());
-    layout->SetOrientation(views::BoxLayout::Orientation::kHorizontal);
-
-    auto* power_icon = AddChildView(std::make_unique<views::ImageView>());
-    power_icon->SetImage(ui::ImageModel::FromVectorIcon(
-        kUnifiedMenuPowerIcon, cros_tokens::kCrosSysOnSurface));
-    power_icon->SetImageSize(kIconSize);
-    auto* arrow_icon = AddChildView(std::make_unique<views::ImageView>());
-    arrow_icon->SetImage(ui::ImageModel::FromVectorIcon(
-        kChevronDownSmallIcon, cros_tokens::kCrosSysOnSurface));
-    arrow_icon->SetImageSize(kIconSize);
-
-    SetBorder(views::CreateEmptyBorder(gfx::Insets(6)));
-
-    // Paints this view to a layer so it will be on top of the
-    // `background_view_`
-    SetPaintToLayer();
-    layer()->SetFillsBoundsOpaquely(false);
-
-    SetAccessibleName(
-        l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_POWER_MENU));
-    SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_POWER_MENU));
-  }
-  PowerButtonContainer(const PowerButtonContainer&) = delete;
-  PowerButtonContainer& operator=(const PowerButtonContainer&) = delete;
-  ~PowerButtonContainer() override = default;
-};
-
 }  // namespace
 
 class PowerButton::MenuController : public ui::SimpleMenuModel::Delegate,
@@ -369,6 +335,42 @@
   raw_ptr<PowerButton, ExperimentalAsh> power_button_ = nullptr;
 };
 
+PowerButtonContainer::PowerButtonContainer(PressedCallback callback)
+    : Button(callback) {
+  auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>());
+  layout->SetOrientation(views::BoxLayout::Orientation::kHorizontal);
+
+  power_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  power_icon_->SetImage(ui::ImageModel::FromVectorIcon(
+      kUnifiedMenuPowerIcon, cros_tokens::kCrosSysOnSurface));
+  power_icon_->SetImageSize(kIconSize);
+  arrow_icon_ = AddChildView(std::make_unique<views::ImageView>());
+  arrow_icon_->SetImage(ui::ImageModel::FromVectorIcon(
+      kChevronDownSmallIcon, cros_tokens::kCrosSysOnSurface));
+  arrow_icon_->SetImageSize(kIconSize);
+
+  SetBorder(views::CreateEmptyBorder(gfx::Insets(6)));
+
+  // Paints this view to a layer so it will be on top of the
+  // `background_view_`
+  SetPaintToLayer();
+  layer()->SetFillsBoundsOpaquely(false);
+
+  SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_POWER_MENU));
+  SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_POWER_MENU));
+}
+
+PowerButtonContainer::~PowerButtonContainer() = default;
+
+void PowerButtonContainer::UpdateIconColor(bool is_active) {
+  auto icon_color_id = is_active ? cros_tokens::kCrosSysSystemOnPrimaryContainer
+                                 : cros_tokens::kCrosSysOnSurface;
+  power_icon_->SetImage(
+      ui::ImageModel::FromVectorIcon(kUnifiedMenuPowerIcon, icon_color_id));
+  arrow_icon_->SetImage(
+      ui::ImageModel::FromVectorIcon(kChevronDownSmallIcon, icon_color_id));
+}
+
 PowerButton::PowerButton(UnifiedSystemTrayController* tray_controller)
     : background_view_(AddChildView(std::make_unique<View>())),
       button_content_(AddChildView(std::make_unique<PowerButtonContainer>(
@@ -432,6 +434,7 @@
     focus_ring->InvalidateLayout();
     focus_ring->SchedulePaint();
   }
+  button_content_->UpdateIconColor(/*is_active*/ IsMenuShowing());
 }
 
 void PowerButton::UpdateRoundedCorners() {
diff --git a/ash/system/unified/power_button.h b/ash/system/unified/power_button.h
index bf307572..00185c3 100644
--- a/ash/system/unified/power_button.h
+++ b/ash/system/unified/power_button.h
@@ -9,6 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "base/memory/raw_ptr.h"
+#include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
 
 namespace ui {
@@ -16,6 +17,7 @@
 }  // namespace ui
 
 namespace views {
+class ImageView;
 class MenuItemView;
 }  // namespace views
 
@@ -23,6 +25,23 @@
 
 class UnifiedSystemTrayController;
 
+// The power button container which contains 2 icons: a power icon and an
+// arrow down icon.
+class PowerButtonContainer : public views::Button {
+ public:
+  explicit PowerButtonContainer(PressedCallback callback);
+  PowerButtonContainer(const PowerButtonContainer&) = delete;
+  PowerButtonContainer& operator=(const PowerButtonContainer&) = delete;
+  ~PowerButtonContainer() override;
+
+  void UpdateIconColor(bool is_active);
+
+ private:
+  // Owned by views hierarchy.
+  raw_ptr<views::ImageView, ExperimentalAsh> power_icon_ = nullptr;
+  raw_ptr<views::ImageView, ExperimentalAsh> arrow_icon_ = nullptr;
+};
+
 // The power button that lives in the `QuickSettingsView` footer. The
 // `background_view_` will change its corner radii and a power button
 // menu will pop up at the same time when it's active.
@@ -39,7 +58,7 @@
   // Getter of the `MenuItemView` for testing.
   views::MenuItemView* GetMenuViewForTesting();
 
-  views::View* button_content_for_testing() { return button_content_; }
+  PowerButtonContainer* button_content_for_testing() { return button_content_; }
 
  private:
   friend class PowerButtonPixelTest;
@@ -67,7 +86,7 @@
 
   // Owned by views hierarchy.
   raw_ptr<views::View, ExperimentalAsh> background_view_ = nullptr;
-  raw_ptr<views::View, ExperimentalAsh> button_content_ = nullptr;
+  raw_ptr<PowerButtonContainer, ExperimentalAsh> button_content_ = nullptr;
 
   // The context menu, which will be set as the controller to show the power
   // button menu view.
diff --git a/ash/system/video_conference/bubble/return_to_app_panel.cc b/ash/system/video_conference/bubble/return_to_app_panel.cc
index 85ac763..48256891c 100644
--- a/ash/system/video_conference/bubble/return_to_app_panel.cc
+++ b/ash/system/video_conference/bubble/return_to_app_panel.cc
@@ -7,9 +7,11 @@
 #include <memory>
 #include <string>
 
+#include "ash/bubble/bubble_utils.h"
 #include "ash/public/cpp/metrics_util.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/strings/grit/ash_strings.h"
+#include "ash/style/typography.h"
 #include "ash/system/video_conference/bubble/bubble_view_ids.h"
 #include "ash/system/video_conference/video_conference_tray_controller.h"
 #include "base/functional/bind.h"
@@ -310,6 +312,11 @@
       views::kFlexBehaviorKey,
       views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
                                views::MaximumFlexSizeRule::kPreferred));
+
+  label->SetAutoColorReadabilityEnabled(false);
+  TypographyProvider::Get()->StyleLabel(TypographyToken::kLegacyBody2, *label);
+  label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
+
   label_ = AddChildView(std::move(label));
 
   if (is_top_row) {
diff --git a/ash/system/video_conference/bubble/set_value_effects_view.cc b/ash/system/video_conference/bubble/set_value_effects_view.cc
index 2b8e666..987ad0e 100644
--- a/ash/system/video_conference/bubble/set_value_effects_view.cc
+++ b/ash/system/video_conference/bubble/set_value_effects_view.cc
@@ -4,8 +4,10 @@
 
 #include "ash/system/video_conference/bubble/set_value_effects_view.h"
 
+#include "ash/bubble/bubble_utils.h"
 #include "ash/style/tab_slider.h"
 #include "ash/style/tab_slider_button.h"
+#include "ash/style/typography.h"
 #include "ash/system/video_conference/bubble/bubble_view_ids.h"
 #include "ash/system/video_conference/effects/video_conference_tray_effects_delegate.h"
 #include "ash/system/video_conference/effects/video_conference_tray_effects_manager_types.h"
@@ -40,6 +42,10 @@
     auto* label = label_container->AddChildView(
         std::make_unique<views::Label>(effect->label_text()));
     label->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+    label->SetAutoColorReadabilityEnabled(false);
+    TypographyProvider::Get()->StyleLabel(TypographyToken::kLegacyButton2,
+                                          *label);
+    label->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
 
     auto* spacer_view =
         label_container->AddChildView(std::make_unique<views::View>());
diff --git a/ash/system/video_conference/bubble/toggle_effects_view.cc b/ash/system/video_conference/bubble/toggle_effects_view.cc
index 9126fc1..4e0bb59c 100644
--- a/ash/system/video_conference/bubble/toggle_effects_view.cc
+++ b/ash/system/video_conference/bubble/toggle_effects_view.cc
@@ -8,9 +8,11 @@
 #include <algorithm>
 #include <memory>
 
+#include "ash/bubble/bubble_utils.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/icon_button.h"
+#include "ash/style/typography.h"
 #include "ash/system/video_conference/bubble/bubble_view_ids.h"
 #include "ash/system/video_conference/effects/video_conference_tray_effects_manager_types.h"
 #include "ash/system/video_conference/video_conference_tray_controller.h"
@@ -90,8 +92,10 @@
 
     auto label = std::make_unique<views::Label>(label_text);
     label->SetID(video_conference::BubbleViewID::kToggleEffectLabel);
-    // Force the label to use requested colors.
     label->SetAutoColorReadabilityEnabled(false);
+    TypographyProvider::Get()->StyleLabel(TypographyToken::kLegacyButton2,
+                                          *label);
+    label->SetEnabledColorId(cros_tokens::kCrosSysOnPrimaryContainer);
     label_ = AddChildView(std::move(label));
 
     SetTooltipText(l10n_util::GetStringFUTF16(
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 220ed474..467ed9858 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -55,6 +55,7 @@
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/no_destructor.h"
 #include "base/rand_util.h"
@@ -415,6 +416,19 @@
   return user_session->user_info.type;
 }
 
+scoped_refptr<base::RefCountedMemory> ReadFile(
+    const base::FilePath& file_path) {
+  if (file_path.empty()) {
+    return nullptr;
+  }
+
+  std::string data;
+  if (!base::ReadFileToString(file_path, &data)) {
+    return nullptr;
+  }
+  return base::MakeRefCounted<base::RefCountedString>(std::move(data));
+}
+
 // Gets |account_id|'s custom wallpaper at |wallpaper_path|. Falls back to the
 // original custom wallpaper. Verifies that the returned path exists. If a valid
 // path cannot be found, returns an empty FilePath. Must run on wallpaper
@@ -1491,15 +1505,20 @@
   return GetWallpaper();
 }
 
-scoped_refptr<base::RefCountedMemory>
-WallpaperControllerImpl::GetPreviewImage() {
+void WallpaperControllerImpl::LoadPreviewImage(
+    LoadPreviewImageCallback callback) {
   if (!current_wallpaper_) {
-    return nullptr;
+    std::move(callback).Run(nullptr);
+    return;
   }
+
   auto image = current_wallpaper_->image();
   image.MakeThreadSafe();
   if (!IsOnlineWallpaper(current_wallpaper_->wallpaper_info().type)) {
-    return EncodeAndResizeImage(image);
+    sequenced_task_runner_->PostTaskAndReplyWithResult(
+        FROM_HERE, base::BindOnce(&EncodeAndResizeImage, image),
+        std::move(callback));
+    return;
   }
 
   auto variants = current_wallpaper_->wallpaper_info().variants;
@@ -1509,18 +1528,19 @@
   // No image with |backdrop::Image::IMAGE_TYPE_PREVIEW_MODE|, fallback to
   // |resized|.
   if (it == variants.end()) {
-    return EncodeAndResizeImage(image);
+    sequenced_task_runner_->PostTaskAndReplyWithResult(
+        FROM_HERE, base::BindOnce(&EncodeAndResizeImage, image),
+        std::move(callback));
+    return;
   }
-  const auto preview_variant = *it;
-  const auto url_to_file_path_map =
-      GetOnlineWallpaperVariantPaths({preview_variant});
-  const base::FilePath& preview_file_path =
-      url_to_file_path_map.at(preview_variant.raw_url.spec());
-  DCHECK(!preview_file_path.empty());
 
-  std::string data;
-  base::ReadFileToString(preview_file_path, &data);
-  return base::MakeRefCounted<base::RefCountedString>(std::move(data));
+  const auto& preview_variant = *it;
+  sequenced_task_runner_->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(&GetExistingOnlineWallpaperPath,
+                     preview_variant.raw_url.spec())
+          .Then(base::BindOnce(&ReadFile)),
+      std::move(callback));
 }
 
 bool WallpaperControllerImpl::IsWallpaperBlurredForLockState() const {
@@ -3292,7 +3312,7 @@
   // wallpaper, but updates the variant of the same wallpaper.
   OnlineWallpaperVariantInfoFetcher::FetchParamsCallback callback =
       base::BindOnce(&WallpaperControllerImpl::OnWallpaperVariantsFetched,
-                     weak_factory_.GetWeakPtr(), info.type,
+                     set_wallpaper_weak_factory_.GetWeakPtr(), info.type,
                      /*start_daily_refresh_timer=*/false, base::DoNothing());
 
   variant_info_fetcher_->FetchOnlineWallpaper(
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h
index 2fa9717..4d8b590 100644
--- a/ash/wallpaper/wallpaper_controller_impl.h
+++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -308,7 +308,7 @@
   void AddObserver(WallpaperControllerObserver* observer) override;
   void RemoveObserver(WallpaperControllerObserver* observer) override;
   gfx::ImageSkia GetWallpaperImage() override;
-  scoped_refptr<base::RefCountedMemory> GetPreviewImage() override;
+  void LoadPreviewImage(LoadPreviewImageCallback callback) override;
   bool IsWallpaperBlurredForLockState() const override;
   bool IsActiveUserWallpaperControlledByPolicy() override;
   bool IsWallpaperControlledByPolicy(
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index b8392bc..93da091b 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -1075,7 +1075,15 @@
   EXPECT_EQ(controller_->calculated_colors()->k_mean_color, SK_ColorBLUE);
   EXPECT_FALSE(pref_manager_->GetCachedKMeanColor("old"));
   EXPECT_TRUE(pref_manager_->GetCachedKMeanColor("new"));
-  EXPECT_TRUE(controller_->GetPreviewImage());
+
+  base::RunLoop load_preview_image_loop;
+  controller_->LoadPreviewImage(base::BindLambdaForTesting(
+      [quit = load_preview_image_loop.QuitClosure()](
+          scoped_refptr<base::RefCountedMemory> image_bytes) {
+        EXPECT_TRUE(image_bytes);
+        std::move(quit).Run();
+      }));
+  load_preview_image_loop.Run();
 }
 
 TEST_F(WallpaperControllerTest, CelebiNotSavedWhenJellyIsDisabled) {
diff --git a/ash/webui/common/resources/cellular_setup/cellular_setup_icons.html b/ash/webui/common/resources/cellular_setup/cellular_setup_icons.html
index 92bcab1..ea376387 100644
--- a/ash/webui/common/resources/cellular_setup/cellular_setup_icons.html
+++ b/ash/webui/common/resources/cellular_setup/cellular_setup_icons.html
@@ -13,3 +13,20 @@
     </defs>
   </svg>
 </iron-iconset-svg>
+
+<!-- Set of SVG illustrations-->
+<iron-iconset-svg name="cellular-setup-illo" size="200">
+  <svg>
+    <defs>
+      <g id="error" viewBox="0 0 201 200" fill="none">
+        <path d="M122.984 41.38c-25.952 0-46.99 21.015-46.99 46.939s21.038 46.94 46.99 46.94 46.991-21.016 46.991-46.94-21.039-46.94-46.991-46.94Zm0 1.928c24.886 0 45.06 20.152 45.06 45.011s-20.174 45.011-45.06 45.011c-24.886 0-45.06-20.152-45.06-45.011s20.174-45.01 45.06-45.01Z" fill="var(--cros-sys-illo-color1-2)"/><path d="M133.249 89.338h-11.877v11.574h-13.557a.39.39 0 0 1-.272-.668l25.044-24.408a.39.39 0 0 1 .662.28v13.222Zm-1.288 3.1-1.815-1.814-2.691 2.688-2.69-2.688-1.816 1.813 2.691 2.688-2.691 2.688 1.816 1.813 2.69-2.675 2.691 2.675 1.815-1.813-2.677-2.688 2.677-2.688Z" fill="var(--cros-sys-illo-color1-2)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M157.595 158.993c0-13.495-10.951-24.435-24.461-24.435-13.509 0-24.461 10.94-24.461 24.435" fill="var(--cros-sys-illo-secondary)"/><path fill-rule="evenodd" clip-rule="evenodd" d="m48.74 134.835 1.893 2.7a2.532 2.532 0 0 1-.62 3.527l-.002.002-24.851 17.382a2.533 2.533 0 0 1-3.525-.622l-1.893-2.7a2.532 2.532 0 0 1 .62-3.527l.002-.002 24.851-17.382a2.532 2.532 0 0 1 3.525.622Z" fill="var(--cros-sys-illo-color5)"/><path d="M50.548 159.017c4.33.999 8.65-1.697 9.648-6.022.999-4.326-1.702-8.643-6.032-9.642-4.33-1-8.649 1.696-9.647 6.022-.999 4.325 1.701 8.642 6.031 9.642Z" fill="var(--cros-sys-illo-secondary)"/><path d="M68.12 147.061c11.198 0 20.276-9.068 20.276-20.254 0-11.187-9.078-20.255-20.277-20.255-11.198 0-20.276 9.068-20.276 20.255 0 11.186 9.078 20.254 20.276 20.254Z" fill="var(--cros-sys-illo-color3)"/><path d="M69.88 130.279v-.746c0-.617.116-1.14.348-1.569.232-.429.64-.909 1.223-1.44.72-.669 1.296-1.334 1.725-1.994.43-.66.644-1.444.644-2.353 0-.909-.228-1.732-.683-2.469-.454-.738-1.09-1.321-1.905-1.749-.815-.429-1.746-.643-2.794-.643-1.407 0-2.566.394-3.476 1.183-.91.789-1.536 1.697-1.88 2.726l2.473 1.029c.223-.669.57-1.222 1.042-1.659.472-.437 1.095-.656 1.867-.656.807 0 1.442.219 1.906.656.463.437.695.99.695 1.659 0 .549-.133 1.02-.4 1.415-.266.394-.699.857-1.3 1.389-.858.771-1.454 1.448-1.79 2.031-.334.583-.501 1.295-.501 2.135v1.055h2.806Zm-1.416 6.018a1.82 1.82 0 0 0 1.352-.565c.369-.378.553-.832.553-1.364 0-.531-.184-.986-.553-1.363a1.82 1.82 0 0 0-1.352-.566c-.532 0-.987.185-1.364.553a1.846 1.846 0 0 0-.567 1.376c0 .532.189.986.567 1.364.377.377.832.565 1.364.565Z" fill="var(--cros-sys-illo-base)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M62.197 156.996c-.52.906.13 2.039 1.17 2.039H73.98c1.039 0 1.688-1.133 1.169-2.039l-5.308-9.255a1.346 1.346 0 0 0-2.338 0l-5.307 9.255Z" fill="var(--cros-sys-illo-color4)"/><path d="M191.495 159.035a.965.965 0 0 1 .093 1.925l-.093.004H13.831a.965.965 0 0 1-.093-1.924l.093-.005h177.664Z" fill="var(--cros-sys-illo-color1-2)"/><path d="M97.578 158.993c7.638 0 13.83-6.192 13.83-13.83s-6.192-13.83-13.83-13.83-13.83 6.192-13.83 13.83 6.192 13.83 13.83 13.83Z" fill="var(--cros-sys-illo-color1)"/>
+      </g>
+      <g id="final-page-success" viewBox="0 0 201 200" fill="none">
+        <path d="M100.366 109.293c-23.295 0-42.18 18.794-42.18 41.977 0 23.183 18.885 41.976 42.18 41.976 23.295 0 42.179-18.793 42.179-41.976s-18.884-41.977-42.179-41.977Zm0 1.908c22.236 0 40.262 17.939 40.262 40.069 0 22.129-18.026 40.068-40.262 40.068s-40.262-17.939-40.262-40.068c0-22.13 18.026-40.069 40.262-40.069Z" fill="var(--cros-sys-illo-color1-2)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M72.382 80.903c0 15.456 12.528 27.985 27.984 27.985 15.455 0 27.984-12.53 27.984-27.985" fill="var(--cros-sys-illo-color1-2)"/><path d="M100.366 124.705c-14.784 0-26.768 11.984-26.768 26.768 0 14.783 11.984 26.767 26.768 26.767 14.783 0 26.767-11.984 26.767-26.767 0-14.784-11.984-26.768-26.767-26.768Zm0 2.549c13.375 0 24.218 10.843 24.218 24.219 0 13.375-10.843 24.218-24.218 24.218-13.376 0-24.219-10.843-24.219-24.218 0-13.376 10.843-24.219 24.219-24.219Z" fill="var(--cros-sys-illo-color1)"/><path d="M106.609 138.351h4.995v22.475h-4.995v-22.475Zm-17.48 12.486h4.994v9.989h-4.995v-9.989Zm8.74-6.243h4.994v16.232h-4.994v-16.232Z" fill="var(--cros-sys-illo-color1)"/><path fill-rule="evenodd" clip-rule="evenodd" d="m114.565 49.036 1.13 2.792a2.636 2.636 0 0 1-1.455 3.433l-.003.001-27.656 11.155a2.636 2.636 0 0 1-3.43-1.456l-1.13-2.792a2.636 2.636 0 0 1 1.455-3.433h.003l27.656-11.156a2.637 2.637 0 0 1 3.43 1.456Z" fill="var(--cros-sys-illo-color1)"/><path d="M100.366 50.643c8.96 0 16.223-7.264 16.223-16.223 0-8.96-7.263-16.223-16.223-16.223-8.96 0-16.223 7.263-16.223 16.223 0 8.96 7.263 16.223 16.223 16.223Z" fill="var(--cros-sys-illo-color2)"/><path fill-rule="evenodd" clip-rule="evenodd" d="m101.896 61.021 8.657 8.643c.476.475.477 1.245.002 1.72l-.002.002-8.657 8.643a1.216 1.216 0 0 1-1.719 0l-8.658-8.643a1.217 1.217 0 0 1-.002-1.72l.002-.002 8.658-8.643a1.217 1.217 0 0 1 1.719 0Z" fill="var(--cros-sys-illo-color3)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M94.252 8.37c-.49-.86.123-1.934 1.104-1.934h10.02c.981 0 1.594 1.075 1.103 1.934l-5.01 8.778c-.49.859-1.716.859-2.207 0l-5.01-8.778Z" fill="var(--cros-sys-illo-color6)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M111.439 25.828c.66.5.791 1.44.291 2.1L99.765 43.748a1.5 1.5 0 0 1-2.15.253l-7.03-5.79a1.5 1.5 0 1 1 1.907-2.316l5.824 4.796 11.022-14.57a1.5 1.5 0 0 1 2.101-.292Z" fill="var(--cros-sys-illo-base)"/>
+      </g>
+      <g id="sim-detect-error" viewBox="0 0 200 200" fill="none">
+        <g clip-path="url(#a)"><path d="M250.017 151.141H98.165a6.753 6.753 0 0 1-6.752-6.752V40.862h165.419v103.465a6.764 6.764 0 0 1-1.978 4.837 6.748 6.748 0 0 1-4.837 1.977v0Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M149.866 141.888h48.45a2.562 2.562 0 0 0 2.563-2.563v-30.351a2.563 2.563 0 0 0-2.563-2.564h-48.45a2.563 2.563 0 0 0-2.563 2.564v30.351a2.562 2.562 0 0 0 2.563 2.563Z" fill="var(--cros-sys-illo-color1-2)"/><path d="M268.71 44.987H79.473a1.375 1.375 0 0 1-1.376-1.375V40.55a2.688 2.688 0 0 1 2.688-2.688h186.612a2.688 2.688 0 0 1 2.688 2.688v3.063a1.375 1.375 0 0 1-1.375 1.375v0Z" fill="var(--cros-sys-illo-base)" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M246.641 48.515h-145.1c-.587 0-1.063.505-1.063 1.127v45.68c0 .622.476 1.127 1.063 1.127h145.1c.587 0 1.063-.505 1.063-1.127v-45.68c0-.622-.476-1.127-1.063-1.127Z" fill="var(--cros-sys-illo-color1-2)"/><path d="M68.147 97.994H43.285a1.025 1.025 0 0 1-1.025-1.077V78.155a1.025 1.025 0 0 1 1.025-1.025h19.48l6.408 6.202v13.585a1.024 1.024 0 0 1-1.026 1.077Z" fill="var(--cros-sys-illo-color1)"/><path d="M52.65 89.142H46.5c-.615 0-1.113.498-1.113 1.113v3.796c0 .614.498 1.113 1.113 1.113h6.15c.615 0 1.113-.499 1.113-1.113v-3.796c0-.615-.498-1.113-1.113-1.113Z" fill="var(--cros-sys-illo-base)"/><path d="M52.65 89.142H46.5c-.615 0-1.113.498-1.113 1.113v3.796c0 .614.498 1.113 1.113 1.113h6.15c.615 0 1.113-.499 1.113-1.113v-3.796c0-.615-.498-1.113-1.113-1.113Z" fill="var(--cros-sys-illo-color1-2)"/><path d="M35.852 70.568v34.038" stroke="var(--cros-sys-illo-color1)" stroke-width="4" stroke-linecap="square" stroke-linejoin="round"/><path d="M35.852 73.797H71.12a2.307 2.307 0 0 1 2.307 2.307V99.02a2.307 2.307 0 0 1-2.307 2.307H35.85" stroke="var(--cros-sys-illo-color1)" stroke-width="2" stroke-linejoin="round"/><path d="M54.614 129.674c23.386 0 42.343-18.958 42.343-42.343 0-23.386-18.957-42.344-42.343-42.344-23.385 0-42.343 18.958-42.343 42.344 0 23.385 18.958 42.343 42.343 42.343Z" stroke="var(--cros-sys-illo-base)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M54.614 129.674c23.386 0 42.343-18.958 42.343-42.343 0-23.386-18.957-42.344-42.343-42.344-23.385 0-42.343 18.958-42.343 42.344 0 23.385 18.958 42.343 42.343 42.343Z" stroke="var(--cros-sys-illo-color1-2)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></g><defs><clipPath id="a"><path fill="var(--cros-sys-illo-base)" d="M0 0h200v200H0z"/></clipPath></defs>
+      </g>
+    </defs>
+  </svg>
+</iron-iconset-svg>
diff --git a/ash/webui/common/resources/cellular_setup/final_page.html b/ash/webui/common/resources/cellular_setup/final_page.html
index ab69855..6fdebc5 100644
--- a/ash/webui/common/resources/cellular_setup/final_page.html
+++ b/ash/webui/common/resources/cellular_setup/final_page.html
@@ -1,28 +1,47 @@
 <style>
-  [slot='page-body'] {
+  #illustration {
     background-image: url(chrome://resources/ash/common/cellular_setup/final_page_success.svg);
     background-position: center center;
     background-repeat: no-repeat;
     background-size: contain;
-    height: 242px;
   }
 
-  .error[slot='page-body'] {
+  #illustration.error {
       background-image: url(chrome://resources/ash/common/cellular_setup/error.svg);
       background-size: contain;
   }
 
   @media(prefers-color-scheme: dark) {
-    [slot='page-body'] {
+    #illustration {
       background-image: url(chrome://resources/ash/common/cellular_setup/final_page_success_dark.svg);
     }
 
-    .error[slot='page-body'] {
+    #illustration.error {
         background-image: url(chrome://resources/ash/common/cellular_setup/error_dark.svg);
     }
   }
+
+  #illustrationJelly {
+    height: 242px;
+    width: 242px;
+    align-self: center;
+  }
+
+  :host-context(body.jelly-enabled) #illustration {
+    display: none;
+  }
+
+  :host-context(body:not(.jelly-enabled)) #illustrationJelly {
+    display: none;
+  }
 </style>
 <base-page title="[[getTitle_(showError)]]"
     message="[[getMessage_(showError)]]">
-  <div class$="[[getPageBodyClass_(showError)]]" slot="page-body"></div>
+  <div id="illustration" class$="[[getPageBodyClass_(showError)]]"
+      slot="page-body">
+  </div>
+  <iron-icon id="illustrationJelly"
+      icon="[[getJellyIllustrationName_(showError)]]"
+      slot="page-body">
+  </iron-icon>
 </base-page>
diff --git a/ash/webui/common/resources/cellular_setup/final_page.js b/ash/webui/common/resources/cellular_setup/final_page.js
index b9b3adb..e22b03a 100644
--- a/ash/webui/common/resources/cellular_setup/final_page.js
+++ b/ash/webui/common/resources/cellular_setup/final_page.js
@@ -68,4 +68,14 @@
   getPageBodyClass_(showError) {
     return showError ? 'error' : '';
   },
+
+  /**
+   * @param {boolean} showError
+   * @return {string}
+   * @private
+   */
+  getJellyIllustrationName_(showError) {
+    return showError ? 'cellular-setup-illo:error' :
+                       'cellular-setup-illo:final-page-success';
+  },
 });
diff --git a/ash/webui/common/resources/cellular_setup/provisioning_page.html b/ash/webui/common/resources/cellular_setup/provisioning_page.html
index dcf96c5..a387ea642 100644
--- a/ash/webui/common/resources/cellular_setup/provisioning_page.html
+++ b/ash/webui/common/resources/cellular_setup/provisioning_page.html
@@ -9,20 +9,32 @@
     width: 100%;
   }
 
-  #error-icon-container {
-    background-image: url(chrome://resources/ash/common/cellular_setup/error.svg);
-    background-position: center center;
-    background-repeat: no-repeat;
-    background-size: contain;
+  #errorIllustration,
+  #errorIllustrationJelly {
     height: 100%;
     width: 100%;
   }
 
+  #errorIllustration {
+    background-image: url(chrome://resources/ash/common/cellular_setup/error.svg);
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: contain;
+  }
+
   @media(prefers-color-scheme: dark) {
-    #error-icon-container {
+    #errorIllustration {
       background-image: url(chrome://resources/ash/common/cellular_setup/error_dark.svg);
     }
   }
+
+  :host-context(body.jelly-enabled) #errorIllustration {
+    display: none;
+  }
+
+  :host-context(body:not(.jelly-enabled)) #errorIllustrationJelly {
+    display: none;
+  }
 </style>
 <base-page title="[[getPageTitle_(
                         showError, carrierName_, hasCarrierPortalLoaded_)]]"
@@ -36,6 +48,9 @@
         hidden$="[[!shouldShowPortal_(
                         showError, hasCarrierPortalLoaded_)]]">
     </div>
-    <div id="error-icon-container" hidden$="[[!showError]]"></div>
+    <div id="errorIllustration" hidden$="[[!showError]]"></div>
+    <iron-icon id="errorIllustrationJelly" icon="cellular-setup-illo:error"
+        hidden$="[[!showError]]">
+    </iron-icon>
   </div>
 </base-page>
diff --git a/ash/webui/common/resources/cellular_setup/setup_loading_page.html b/ash/webui/common/resources/cellular_setup/setup_loading_page.html
index 6d4b7430..167f967 100644
--- a/ash/webui/common/resources/cellular_setup/setup_loading_page.html
+++ b/ash/webui/common/resources/cellular_setup/setup_loading_page.html
@@ -7,13 +7,17 @@
     margin-bottom: 54px;
   }
 
+  #simDetectError,
+  #simDetectErrorJelly {
+    height: 100%;
+    width: 100%;
+  }
+
   #simDetectError {
     background-image: url(chrome://resources/ash/common/cellular_setup/sim_detect_error.svg);
     background-position: center center;
     background-repeat: no-repeat;
     background-size: contain;
-    height: 100%;
-    width: 100%;
   }
 
   @media(prefers-color-scheme: dark) {
@@ -22,6 +26,14 @@
     }
   }
 
+  :host-context(body.jelly-enabled) #simDetectError {
+    display: none;
+  }
+
+  :host-context(body:not(.jelly-enabled)) #simDetectErrorJelly {
+    display: none;
+  }
+
   #pageBody {
     height: 222px;
   }
@@ -49,5 +61,9 @@
     </template>
     <div id="simDetectError" hidden$="[[!isSimDetectError]]">
     </div>
+    <iron-icon id="simDetectErrorJelly"
+        icon="cellular-setup-illo:sim-detect-error"
+        hidden$="[[!isSimDetectError]]">
+    </iron-icon>
   </div>
 </base-page>
diff --git a/ash/webui/personalization_app/BUILD.gn b/ash/webui/personalization_app/BUILD.gn
index 00798c8..1cb5dd7c 100644
--- a/ash/webui/personalization_app/BUILD.gn
+++ b/ash/webui/personalization_app/BUILD.gn
@@ -53,8 +53,6 @@
     "test/fake_personalization_app_ambient_provider.h",
     "test/fake_personalization_app_keyboard_backlight_provider.cc",
     "test/fake_personalization_app_keyboard_backlight_provider.h",
-    "test/fake_personalization_app_theme_provider.cc",
-    "test/fake_personalization_app_theme_provider.h",
     "test/fake_personalization_app_user_provider.cc",
     "test/fake_personalization_app_user_provider.h",
     "test/personalization_app_mojom_banned_browsertest_fixture.cc",
diff --git a/ash/webui/personalization_app/README.md b/ash/webui/personalization_app/README.md
index 41bbf7e..89ba906 100644
--- a/ash/webui/personalization_app/README.md
+++ b/ash/webui/personalization_app/README.md
@@ -49,8 +49,9 @@
   * Uses fixture `personalization_app_browsertest_fixture.h`
     * wallpaper mocked out at network layer by mocking out wallpaper fetchers
     via `TestWallpaperFetcherDelegate`
+    * uses a real theme provider
     * all others mock out mojom layer via fake mojom providers
-    `FakePersonalizationApp{Ambient,KeyboardBacklight,Theme,User}Provider`
+    `FakePersonalizationApp{Ambient,KeyboardBacklight,User}Provider`
 * System Web App integration tests
   * `personalization_app_integration_browsertest.cc`
   * `browser_tests --gtest_filter=*PersonalizationAppIntegration*`
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc
deleted file mode 100644
index 276939c8..0000000
--- a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.cc
+++ /dev/null
@@ -1,73 +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 "ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h"
-
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace ash::personalization_app {
-
-FakePersonalizationAppThemeProvider::FakePersonalizationAppThemeProvider(
-    content::WebUI* web_ui) {}
-
-FakePersonalizationAppThemeProvider::~FakePersonalizationAppThemeProvider() =
-    default;
-
-void FakePersonalizationAppThemeProvider::BindInterface(
-    mojo::PendingReceiver<ash::personalization_app::mojom::ThemeProvider>
-        receiver) {
-  theme_receiver_.reset();
-  theme_receiver_.Bind(std::move(receiver));
-}
-
-void FakePersonalizationAppThemeProvider::SetThemeObserver(
-    mojo::PendingRemote<ash::personalization_app::mojom::ThemeObserver>
-        observer) {}
-
-void FakePersonalizationAppThemeProvider::SetColorModePref(
-    bool dark_mode_enabled) {
-  return;
-}
-
-void FakePersonalizationAppThemeProvider::SetColorModeAutoScheduleEnabled(
-    bool enabled) {
-  return;
-}
-
-void FakePersonalizationAppThemeProvider::IsDarkModeEnabled(
-    IsDarkModeEnabledCallback callback) {
-  std::move(callback).Run(/*darkModeEnabled=*/false);
-}
-
-void FakePersonalizationAppThemeProvider::IsColorModeAutoScheduleEnabled(
-    IsColorModeAutoScheduleEnabledCallback callback) {
-  std::move(callback).Run(/*enabled=*/false);
-}
-
-void FakePersonalizationAppThemeProvider::SetColorScheme(
-    ash::ColorScheme color_scheme) {
-  return;
-}
-
-void FakePersonalizationAppThemeProvider::SetStaticColor(
-    ::SkColor static_color) {
-  return;
-}
-
-void FakePersonalizationAppThemeProvider::GetColorScheme(
-    GetColorSchemeCallback callback) {
-  std::move(callback).Run(ash::ColorScheme::kTonalSpot);
-}
-
-void FakePersonalizationAppThemeProvider::GenerateSampleColorSchemes(
-    GenerateSampleColorSchemesCallback callback) {
-  std::vector<ash::SampleColorScheme> samples;
-  std::move(callback).Run(samples);
-}
-
-void FakePersonalizationAppThemeProvider::GetStaticColor(
-    GetStaticColorCallback callback) {
-  std::move(callback).Run(SK_ColorBLUE);
-}
-}  // namespace ash::personalization_app
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h b/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h
deleted file mode 100644
index addb36b3..0000000
--- a/ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h
+++ /dev/null
@@ -1,71 +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 ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_THEME_PROVIDER_H_
-#define ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_THEME_PROVIDER_H_
-
-#include "ash/webui/personalization_app/personalization_app_theme_provider.h"
-
-#include <stdint.h>
-
-#include "ash/public/cpp/wallpaper/wallpaper_types.h"
-#include "ash/webui/personalization_app/mojom/personalization_app.mojom.h"
-#include "base/unguessable_token.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-
-namespace content {
-class WebUI;
-}  // namespace content
-
-namespace ash::personalization_app {
-
-class FakePersonalizationAppThemeProvider
-    : public PersonalizationAppThemeProvider {
- public:
-  explicit FakePersonalizationAppThemeProvider(content::WebUI* web_ui);
-
-  FakePersonalizationAppThemeProvider(
-      const FakePersonalizationAppThemeProvider&) = delete;
-  FakePersonalizationAppThemeProvider& operator=(
-      const FakePersonalizationAppThemeProvider&) = delete;
-
-  ~FakePersonalizationAppThemeProvider() override;
-
-  void BindInterface(
-      mojo::PendingReceiver<ash::personalization_app::mojom::ThemeProvider>
-          receiver) override;
-
-  void SetThemeObserver(
-      mojo::PendingRemote<ash::personalization_app::mojom::ThemeObserver>
-          observer) override;
-
-  void SetColorModePref(bool dark_mode_enabled) override;
-
-  void SetColorModeAutoScheduleEnabled(bool enabled) override;
-
-  void SetColorScheme(ash::ColorScheme color_scheme) override;
-
-  void SetStaticColor(::SkColor static_color) override;
-
-  void GetColorScheme(GetColorSchemeCallback callback) override;
-
-  void GetStaticColor(GetStaticColorCallback callback) override;
-
-  void GenerateSampleColorSchemes(
-      GenerateSampleColorSchemesCallback callback) override;
-
-  void IsDarkModeEnabled(IsDarkModeEnabledCallback callback) override;
-
-  void IsColorModeAutoScheduleEnabled(
-      IsColorModeAutoScheduleEnabledCallback callback) override;
-
- private:
-  mojo::Receiver<ash::personalization_app::mojom::ThemeProvider>
-      theme_receiver_{this};
-};
-
-}  // namespace ash::personalization_app
-
-#endif  // ASH_WEBUI_PERSONALIZATION_APP_TEST_FAKE_PERSONALIZATION_APP_THEME_PROVIDER_H_
diff --git a/ash/webui/scanning/BUILD.gn b/ash/webui/scanning/BUILD.gn
index fd151dd..92dd0279 100644
--- a/ash/webui/scanning/BUILD.gn
+++ b/ash/webui/scanning/BUILD.gn
@@ -24,6 +24,7 @@
 
   deps = [
     "//ash/constants",
+    "//ash/webui/common:chrome_os_webui_config",
     "//ash/webui/common/backend:backend",
     "//ash/webui/common/mojom",
     "//ash/webui/resources:scanning_app_resources",
diff --git a/ash/webui/scanning/scanning_app_delegate.h b/ash/webui/scanning/scanning_app_delegate.h
index 3fca1ee..5e3ffe0 100644
--- a/ash/webui/scanning/scanning_app_delegate.h
+++ b/ash/webui/scanning/scanning_app_delegate.h
@@ -9,19 +9,28 @@
 #include <string>
 #include <vector>
 
+#include "ash/webui/scanning/mojom/scanning.mojom-forward.h"
 #include "base/files/file_path.h"
 #include "base/functional/callback_forward.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 
 namespace ui {
 class SelectFilePolicy;
 }  // namespace ui
 
+namespace content {
+class WebUI;
+}  // namespace content
+
 namespace ash {
 
 // A delegate which exposes browser functionality from //chrome to the Scan app
 // UI.
 class ScanningAppDelegate {
  public:
+  using BindScanServiceCallback = base::RepeatingCallback<void(
+      mojo::PendingReceiver<scanning::mojom::ScanService>)>;
+
   virtual ~ScanningAppDelegate() = default;
 
   // Returns a ChromeSelectFilePolicy used to open a select dialog.
@@ -54,6 +63,9 @@
   virtual void ShowFileInFilesApp(
       const base::FilePath& path_to_file,
       base::OnceCallback<void(const bool)> callback) = 0;
+
+  virtual BindScanServiceCallback GetBindScanServiceCallback(
+      content::WebUI* web_ui) = 0;
 };
 
 }  // namespace ash
diff --git a/ash/webui/scanning/scanning_handler_unittest.cc b/ash/webui/scanning/scanning_handler_unittest.cc
index 34c75c18..f6a3c64 100644
--- a/ash/webui/scanning/scanning_handler_unittest.cc
+++ b/ash/webui/scanning/scanning_handler_unittest.cc
@@ -159,6 +159,11 @@
 
   std::string GetScanSettingsFromPrefs() override { return scan_settings_; }
 
+  BindScanServiceCallback GetBindScanServiceCallback(
+      content::WebUI* web_ui) override {
+    return base::DoNothing();
+  }
+
   // Returns the file paths saved in OpenFilesInMediaApp().
   const std::vector<base::FilePath>& file_paths() const { return file_paths_; }
 
diff --git a/ash/webui/scanning/scanning_ui.cc b/ash/webui/scanning/scanning_ui.cc
index 1bb970c1..e0cd8a5 100644
--- a/ash/webui/scanning/scanning_ui.cc
+++ b/ash/webui/scanning/scanning_ui.cc
@@ -156,10 +156,10 @@
 
 ScanningUI::ScanningUI(
     content::WebUI* web_ui,
-    BindScanServiceCallback callback,
     std::unique_ptr<ScanningAppDelegate> scanning_app_delegate)
     : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */),
-      bind_pending_receiver_callback_(std::move(callback)) {
+      bind_pending_receiver_callback_(
+          scanning_app_delegate->GetBindScanServiceCallback(web_ui)) {
   content::WebUIDataSource* html_source =
       content::WebUIDataSource::CreateAndAdd(
           web_ui->GetWebContents()->GetBrowserContext(),
diff --git a/ash/webui/scanning/scanning_ui.h b/ash/webui/scanning/scanning_ui.h
index 3d3d4c0b..95be1f2 100644
--- a/ash/webui/scanning/scanning_ui.h
+++ b/ash/webui/scanning/scanning_ui.h
@@ -7,10 +7,13 @@
 
 #include <memory>
 
+#include "ash/webui/common/chrome_os_webui_config.h"
 #include "ash/webui/common/mojom/accessibility_features.mojom.h"
 #include "ash/webui/scanning/mojom/scanning.mojom-forward.h"
 #include "ash/webui/scanning/scanning_handler.h"
+#include "ash/webui/scanning/url_constants.h"
 #include "base/functional/callback.h"
+#include "content/public/common/url_constants.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/webui/mojo_web_ui_controller.h"
 #include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h"
@@ -28,6 +31,16 @@
 class AccessibilityFeatures;
 
 class ScanningAppDelegate;
+class ScanningUI;
+
+// The WebUIConfig for chrome://scanning.
+class ScanningUIConfig : public ChromeOSWebUIConfig<ScanningUI> {
+ public:
+  explicit ScanningUIConfig(CreateWebUIControllerFunc create_controller_func)
+      : ChromeOSWebUIConfig(content::kChromeUIScheme,
+                            ash::kChromeUIScanningAppHost,
+                            create_controller_func) {}
+};
 
 // The WebUI for chrome://scanning.
 class ScanningUI : public ui::MojoWebUIController {
@@ -35,10 +48,7 @@
   using BindScanServiceCallback = base::RepeatingCallback<void(
       mojo::PendingReceiver<scanning::mojom::ScanService>)>;
 
-  // |callback| should bind the pending receiver to an implementation of
-  // ash::scanning::mojom::ScanService.
   ScanningUI(content::WebUI* web_ui,
-             BindScanServiceCallback callback,
              std::unique_ptr<ScanningAppDelegate> scanning_app_delegate);
   ~ScanningUI() override;
 
@@ -62,6 +72,8 @@
           receiver);
 
  private:
+  // Callback to bind the pending receiver to an implementation of
+  // ash::scanning::mojom::ScanService.
   const BindScanServiceCallback bind_pending_receiver_callback_;
 
   std::unique_ptr<AccessibilityFeatures> accessibility_features_;
diff --git a/ash/webui/shimless_rma/BUILD.gn b/ash/webui/shimless_rma/BUILD.gn
index c937b5e..448d5d8 100644
--- a/ash/webui/shimless_rma/BUILD.gn
+++ b/ash/webui/shimless_rma/BUILD.gn
@@ -17,6 +17,7 @@
   deps = [
     "//ash/constants",
     "//ash/public/cpp:cpp",
+    "//ash/webui/common:chrome_os_webui_config",
     "//ash/webui/resources:shimless_rma_resources",
     "//ash/webui/shimless_rma/backend",
     "//ash/webui/shimless_rma/mojom",
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc
index ce74949..ea0142d 100644
--- a/ash/webui/shimless_rma/shimless_rma.cc
+++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -407,6 +407,17 @@
 
 }  // namespace shimless_rma
 
+ShimlessRMADialogUIConfig::ShimlessRMADialogUIConfig(
+    CreateWebUIControllerFunc create_controller_func)
+    : ChromeOSWebUIConfig(content::kChromeUIScheme,
+                          ash::kChromeUIShimlessRMAHost,
+                          create_controller_func) {}
+
+bool ShimlessRMADialogUIConfig::IsWebUIEnabled(
+    content::BrowserContext* browser_context) {
+  return shimless_rma::HasLaunchRmaSwitchAndIsAllowed();
+}
+
 ShimlessRMADialogUI::ShimlessRMADialogUI(
     content::WebUI* web_ui,
     std::unique_ptr<shimless_rma::ShimlessRmaDelegate> shimless_rma_delegate)
diff --git a/ash/webui/shimless_rma/shimless_rma.h b/ash/webui/shimless_rma/shimless_rma.h
index 19acd59..570eb18 100644
--- a/ash/webui/shimless_rma/shimless_rma.h
+++ b/ash/webui/shimless_rma/shimless_rma.h
@@ -7,18 +7,24 @@
 
 #include <memory>
 
+#include "ash/webui/common/chrome_os_webui_config.h"
 #include "ash/webui/shimless_rma/backend/shimless_rma_service.h"
 #include "ash/webui/shimless_rma/mojom/shimless_rma.mojom-forward.h"
+#include "ash/webui/shimless_rma/url_constants.h"
 #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h"
+#include "content/public/common/url_constants.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
 
 namespace content {
+class BrowserContext;
 class WebUI;
 }  // namespace content
 
 namespace ash {
 
+class ShimlessRMADialogUI;
+
 namespace shimless_rma {
 class ShimlessRmaDelegate;
 
@@ -29,6 +35,16 @@
 bool HasLaunchRmaSwitchAndIsAllowed();
 }  // namespace shimless_rma
 
+// The WebUIConfig for ShimlessRMA or chrome://shimless-rma.
+class ShimlessRMADialogUIConfig
+    : public ChromeOSWebUIConfig<ShimlessRMADialogUI> {
+ public:
+  explicit ShimlessRMADialogUIConfig(
+      CreateWebUIControllerFunc create_controller_func);
+
+  bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
+};
+
 // The WebUI for ShimlessRMA or chrome://shimless-rma.
 class ShimlessRMADialogUI : public ui::MojoWebDialogUI {
  public:
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h
index f5ad7581..0117152 100644
--- a/ash/wm/overview/overview_grid.h
+++ b/ash/wm/overview/overview_grid.h
@@ -475,8 +475,7 @@
 
   // Gets the layout of the overview items. Layout is done in 2 stages
   // maintaining fixed MRU ordering.
-  // 1. Optimal height is determined. In this blacklist dummy
-  // slave |height| is bisected to find
+  // 1. Optimal height is determined. In this stage `height` is bisected to find
   //    maximum height which still allows all the windows to fit.
   // 2. Row widths are balanced. In this stage the available width is reduced
   //    until some windows are no longer fitting or until the difference between
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni
index 6be2342..cd5f217 100644
--- a/base/allocator/partition_allocator/partition_alloc.gni
+++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -16,7 +16,7 @@
   # NaCl targets don't use 64-bit pointers.
   has_64_bit_pointers = false
 } else if (current_cpu == "x64" || current_cpu == "arm64" ||
-           current_cpu == "loong64") {
+           current_cpu == "loong64" || current_cpu == "riscv64") {
   has_64_bit_pointers = true
 } else if (current_cpu == "x86" || current_cpu == "arm") {
   has_64_bit_pointers = false
diff --git a/base/hash/hash.cc b/base/hash/hash.cc
index 1350081..389d50a 100644
--- a/base/hash/hash.cc
+++ b/base/hash/hash.cc
@@ -157,11 +157,6 @@
   return Scramble(HashInts32Impl(value1, value2));
 }
 
-// Implement hashing for pairs of up-to 64-bit integer values.
-// We use the compound integer hash method to produce a 64-bit hash code, by
-// breaking the two 64-bit inputs into 4 32-bit values:
-// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
-// Then we reduce our result to 32 bits if required, similar to above.
 size_t HashInts64(uint64_t value1, uint64_t value2) {
   return Scramble(HashInts64Impl(value1, value2));
 }
diff --git a/base/mac/launch_application.h b/base/mac/launch_application.h
index 4e33428..94dbea73 100644
--- a/base/mac/launch_application.h
+++ b/base/mac/launch_application.h
@@ -14,7 +14,6 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/functional/callback_forward.h"
-#include "base/types/expected.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 // Launches an application.
@@ -34,7 +33,7 @@
 };
 
 using LaunchApplicationCallback =
-    base::OnceCallback<void(base::expected<NSRunningApplication*, NSError*>)>;
+    base::OnceCallback<void(NSRunningApplication*, NSError*)>;
 
 using CommandLineArgs =
     absl::variant<absl::monostate, CommandLine, std::vector<std::string>>;
@@ -52,8 +51,9 @@
 //   - `callback`: the result callback
 //
 // When the launch is complete, `callback` is called on the main thread. If the
-// launch succeeded, it will be called with an `NSRunningApplication*`. If the
-// launch failed, it will be called with an `NSError*`.
+// launch succeeded, it will be called with an `NSRunningApplication*` and the
+// `NSError*` will be nil. If the launch failed, it will be called with an
+// `NSError*`, and the `NSRunningApplication*` will be nil.
 BASE_EXPORT void LaunchApplication(const FilePath& app_bundle_path,
                                    const CommandLineArgs& command_line_args,
                                    const std::vector<std::string>& url_specs,
diff --git a/base/mac/launch_application.mm b/base/mac/launch_application.mm
index beefe92..ce3315c7 100644
--- a/base/mac/launch_application.mm
+++ b/base/mac/launch_application.mm
@@ -87,9 +87,9 @@
   if (!bundle_url) {
     dispatch_async(dispatch_get_main_queue(), ^{
       std::move(callback_block_access)
-          .Run(base::unexpected([NSError errorWithDomain:NSCocoaErrorDomain
-                                                    code:NSFileNoSuchFileError
-                                                userInfo:nil]));
+          .Run(nil, [NSError errorWithDomain:NSCocoaErrorDomain
+                                        code:NSFileNoSuchFileError
+                                    userInfo:nil]);
     });
     return;
   }
@@ -109,9 +109,9 @@
           dispatch_async(dispatch_get_main_queue(), ^{
             if (error) {
               LOG(ERROR) << base::SysNSStringToUTF8(error.localizedDescription);
-              std::move(callback_block_access).Run(base::unexpected(error));
+              std::move(callback_block_access).Run(nil, error);
             } else {
-              std::move(callback_block_access).Run(app);
+              std::move(callback_block_access).Run(app, nil);
             }
           });
         };
@@ -155,9 +155,9 @@
     dispatch_async(dispatch_get_main_queue(), ^{
       if (error) {
         LOG(ERROR) << base::SysNSStringToUTF8(error.localizedDescription);
-        std::move(callback_block_access).Run(base::unexpected(error));
+        std::move(callback_block_access).Run(nil, error);
       } else {
-        std::move(callback_block_access).Run(app);
+        std::move(callback_block_access).Run(app, nil);
       }
     });
   }
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index c0e4bc4..0504b04 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -8,6 +8,7 @@
 #include <limits>
 #include <utility>
 
+#include "base/debug/crash_logging.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer.h"
@@ -456,6 +457,34 @@
     return;
   }
 
+  // TODO(crbug/1432981): Remove this. Used to investigate unexpected failures.
+  HistogramType type = existing->GetHistogramType();
+  if ((type == HistogramType::HISTOGRAM ||
+       type == HistogramType::LINEAR_HISTOGRAM ||
+       type == HistogramType::BOOLEAN_HISTOGRAM ||
+       type == HistogramType::CUSTOM_HISTOGRAM) &&
+      histogram->GetHistogramType() == type) {
+    const BucketRanges* existing_buckets =
+        static_cast<Histogram*>(existing)->bucket_ranges();
+    const BucketRanges* histogram_buckets =
+        static_cast<Histogram*>(histogram)->bucket_ranges();
+    DCHECK(existing_buckets->HasValidChecksum() &&
+           histogram_buckets->HasValidChecksum());
+
+    // If the buckets do not match, then the call to AddSamples() below should
+    // trigger a NOTREACHED(). This may be indicative that a child process is
+    // emitting a histogram with different parameters than the browser
+    // process, for example.
+    if (!existing_buckets->Equals(histogram_buckets)) {
+#if !BUILDFLAG(IS_NACL)
+      SCOPED_CRASH_KEY_STRING256("PersistentHistogramAllocator", "histogram",
+                                 existing->histogram_name());
+#endif  // !BUILDFLAG(IS_NACL)
+      existing->AddSamples(*histogram->SnapshotDelta());
+      return;
+    }
+  }
+
   // Merge the delta from the passed object to the one in the SR.
   existing->AddSamples(*histogram->SnapshotDelta());
 }
diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni
index 1aad3d6..0de9792 100644
--- a/build/config/clang/clang.gni
+++ b/build/config/clang/clang.gni
@@ -19,4 +19,12 @@
       ((is_linux && !is_castos) || (is_android && !is_cast_android))
 
   clang_base_path = default_clang_base_path
+
+  # Specifies whether or not bitcode should be embedded during compilation.
+  # This is used for creating a MLGO corpus from Chromium in the non-ThinLTO case.
+  clang_embed_bitcode = false
+
+  # Set to true to enable output of ThinLTO index and import files used for
+  # creating a Chromium MLGO corpus in the ThinLTO case.
+  lld_emit_indexes_and_imports = false
 }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index ec1689f..b61ac1f 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -870,6 +870,24 @@
     }
   }
 
+  if (clang_embed_bitcode) {
+    assert(!use_thin_lto,
+           "clang_embed_bitcode is only supported in non-ThinLTO builds")
+    cflags += [
+      "-Xclang",
+      "-fembed-bitcode=all",
+    ]
+  }
+
+  if (lld_emit_indexes_and_imports) {
+    assert(use_thin_lto,
+           "lld_emit_indexes_and_imports is only supported with ThinLTO builds")
+    ldflags += [
+      "-Wl,--save-temps=import",
+      "-Wl,--thinlto-emit-index-files",
+    ]
+  }
+
   # Pass the same C/C++ flags to the objective C/C++ compiler.
   cflags_objc += cflags_c
   cflags_objcc += cflags_cc
@@ -919,6 +937,14 @@
     # directory from appearing in build outputs.
     "-Zremap-cwd-prefix=.",
   ]
+
+  if (!is_win || force_rustc_color_output) {
+    # Colorize error output. The analogous flag is passed for clang. This must
+    # be platform-gated since rustc will unconditionally output ANSI escape
+    # sequences, ignoring the platform, when stderr is not a terminal.
+    rustflags += [ "--color=always" ]
+  }
+
   if (rust_abi_target != "") {
     rustflags += [ "--target=$rust_abi_target" ]
   }
diff --git a/build/config/rust.gni b/build/config/rust.gni
index 41d4ca85..c0b8450 100644
--- a/build/config/rust.gni
+++ b/build/config/rust.gni
@@ -72,6 +72,11 @@
   # it is the regular toolchain, but when that toolchain has sanitizers, then
   # this variable is changed to avoid them.
   host_toolchain_no_sanitizers = host_toolchain
+
+  # Force-enable `--color=always` for rustc, even when it would be disabled for
+  # a platform. Mostly applicable to Windows, where new versions can handle ANSI
+  # escape sequences but it's not reliable in general.
+  force_rustc_color_output = false
 }
 
 # Use a separate declare_args so these variables' defaults can depend on the
diff --git a/build/install-build-deps.py b/build/install-build-deps.py
new file mode 100755
index 0000000..9409a8f
--- /dev/null
+++ b/build/install-build-deps.py
@@ -0,0 +1,916 @@
+#!/usr/bin/env python3
+
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Script to install everything needed to build chromium
+# including items requiring sudo privileges.
+# See https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md
+
+import argparse
+import functools
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+
+@functools.cache
+def build_apt_package_list():
+  print("Building apt package list.", file=sys.stderr)
+  output = subprocess.check_output(["apt-cache", "dumpavail"], text=True)
+  arch_map = {"i386": ":i386"}
+  package_regex = re.compile(r"^Package: (.+?)$.+?^Architecture: (.+?)$",
+                             re.M | re.S)
+  return set(package + arch_map.get(arch, "")
+             for package, arch in re.findall(package_regex, output))
+
+
+def package_exists(package_name: str) -> bool:
+  return package_name in build_apt_package_list()
+
+
+def parse_args(argv):
+  parser = argparse.ArgumentParser(
+      description="Install Chromium build dependencies.")
+  parser.add_argument("--syms",
+                      action="store_true",
+                      help="Enable installation of debugging symbols")
+  parser.add_argument(
+      "--no-syms",
+      action="store_false",
+      dest="syms",
+      help="Disable installation of debugging symbols",
+  )
+  parser.add_argument(
+      "--lib32",
+      action="store_true",
+      help="Enable installation of 32-bit libraries, e.g. for V8 snapshot",
+  )
+  parser.add_argument(
+      "--android",
+      action="store_true",
+      help="Enable installation of android dependencies",
+  )
+  parser.add_argument(
+      "--no-android",
+      action="store_false",
+      dest="android",
+      help="Disable installation of android dependencies",
+  )
+  parser.add_argument("--arm",
+                      action="store_true",
+                      help="Enable installation of arm cross toolchain")
+  parser.add_argument(
+      "--no-arm",
+      action="store_false",
+      dest="arm",
+      help="Disable installation of arm cross toolchain",
+  )
+  parser.add_argument(
+      "--chromeos-fonts",
+      action="store_true",
+      help="Enable installation of Chrome OS fonts",
+  )
+  parser.add_argument(
+      "--no-chromeos-fonts",
+      action="store_false",
+      dest="chromeos_fonts",
+      help="Disable installation of Chrome OS fonts",
+  )
+  parser.add_argument(
+      "--nacl",
+      action="store_true",
+      help="Enable installation of prerequisites for building NaCl",
+  )
+  parser.add_argument(
+      "--no-nacl",
+      action="store_false",
+      dest="nacl",
+      help="Disable installation of prerequisites for building NaCl",
+  )
+  parser.add_argument(
+      "--backwards-compatible",
+      action="store_true",
+      help=
+      "Enable installation of packages that are no longer currently needed and"
+      + "have been removed from this script. Useful for bisection.",
+  )
+  parser.add_argument(
+      "--no-backwards-compatible",
+      action="store_false",
+      dest="backwards_compatible",
+      help=
+      "Disable installation of packages that are no longer currently needed and"
+      + "have been removed from this script.",
+  )
+  parser.add_argument("--no-prompt",
+                      action="store_true",
+                      help="Automatic yes to prompts")
+  parser.add_argument(
+      "--quick-check",
+      action="store_true",
+      help="Quickly try to determine if dependencies are installed",
+  )
+  parser.add_argument(
+      "--unsupported",
+      action="store_true",
+      help="Attempt installation even on unsupported systems",
+  )
+
+  options = parser.parse_args(argv)
+
+  if options.arm or options.android:
+    options.lib32 = True
+
+  return options
+
+
+def check_lsb_release():
+  if not shutil.which("lsb_release"):
+    print("ERROR: lsb_release not found in $PATH", file=sys.stderr)
+    print("try: sudo apt-get install lsb-release", file=sys.stderr)
+    sys.exit(1)
+
+
+@functools.cache
+def distro_codename():
+  return subprocess.check_output(["lsb_release", "--codename", "--short"],
+                                 text=True).strip()
+
+
+def check_distro(options):
+  if options.unsupported or options.quick_check:
+    return
+
+  distro_id = subprocess.check_output(["lsb_release", "--id",
+                                       "--short"].decode().strip())
+
+  supported_codenames = ["bionic", "focal", "jammy"]
+  supported_ids = ["Debian"]
+
+  if (distro_codename() not in supported_codenames
+      and distro_id not in supported_ids):
+    print(
+        "WARNING: The following distributions are supported,",
+        "but distributions not in the list below can also try to install",
+        "dependencies by passing the `--unsupported` parameter",
+        "\tUbuntu 18.04 LTS (bionic with EoL April 2028)",
+        "\tUbuntu 20.04 LTS (focal with EoL April 2030)",
+        "\tUbuntu 22.04 LTS (jammy with EoL April 2032)",
+        "\tDebian 10 (buster) or later",
+        sep="\n",
+        file=sys.stderr,
+    )
+    sys.exit(1)
+
+
+def check_architecture():
+  architecture = subprocess.check_output(["uname", "-m"], text=True).strip()
+  if architecture not in ["i686", "x86_64"]:
+    print("Only x86 architectures are currently supported", file=sys.stderr)
+    sys.exit(1)
+
+
+def check_root():
+  if os.geteuid() != 0:
+    print("Running as non-root user.", file=sys.stderr)
+    print("You might have to enter your password one or more times for 'sudo'.",
+          file=sys.stderr)
+    print(file=sys.stderr)
+
+
+def apt_update(options):
+  if options.lib32 or options.nacl:
+    subprocess.check_call(["sudo", "dpkg", "--add-architecture", "i386"])
+  subprocess.check_call(["sudo", "apt-get", "update"])
+
+
+# Packages needed for development
+def dev_list():
+  packages = [
+      "bison",
+      "bzip2",
+      "cdbs",
+      "curl",
+      "dbus-x11",
+      "devscripts",
+      "dpkg-dev",
+      "elfutils",
+      "fakeroot",
+      "flex",
+      "git-core",
+      "gperf",
+      "libasound2-dev",
+      "libatspi2.0-dev",
+      "libbrlapi-dev",
+      "libbz2-dev",
+      "libc6-dev",
+      "libcairo2-dev",
+      "libcap-dev",
+      "libcups2-dev",
+      "libcurl4-gnutls-dev",
+      "libdrm-dev",
+      "libelf-dev",
+      "libevdev-dev",
+      "libffi-dev",
+      "libgbm-dev",
+      "libglib2.0-dev",
+      "libglu1-mesa-dev",
+      "libgtk-3-dev",
+      "libkrb5-dev",
+      "libnspr4-dev",
+      "libnss3-dev",
+      "libpam0g-dev",
+      "libpci-dev",
+      "libpulse-dev",
+      "libsctp-dev",
+      "libspeechd-dev",
+      "libsqlite3-dev",
+      "libssl-dev",
+      "libsystemd-dev",
+      "libudev-dev",
+      "libva-dev",
+      "libwww-perl",
+      "libxshmfence-dev",
+      "libxslt1-dev",
+      "libxss-dev",
+      "libxt-dev",
+      "libxtst-dev",
+      "lighttpd",
+      "locales",
+      "openbox",
+      "p7zip",
+      "patch",
+      "perl",
+      "pkg-config",
+      "rpm",
+      "ruby",
+      "subversion",
+      "uuid-dev",
+      "wdiff",
+      "x11-utils",
+      "xcompmgr",
+      "xz-utils",
+      "zip",
+  ]
+
+  # Packages needed for chromeos only
+  packages += [
+      "libbluetooth-dev",
+      "libxkbcommon-dev",
+      "mesa-common-dev",
+      "zstd",
+  ]
+
+  if package_exists("realpath"):
+    packages.append("realpath")
+
+  if package_exists("libjpeg-dev"):
+    packages.append("libjpeg-dev")
+  else:
+    packages.append("libjpeg62-dev")
+
+  if package_exists("libudev1"):
+    packages.append("libudev1")
+  else:
+    packages.append("libudev0")
+
+  if package_exists("libbrlapi0.8"):
+    packages.append("libbrlapi0.8")
+  elif package_exists("libbrlapi0.7"):
+    packages.append("libbrlapi0.7")
+  elif package_exists("libbrlapi0.6"):
+    packages.append("libbrlapi0.6")
+  else:
+    packages.append("libbrlapi0.5")
+
+  if package_exists("libav-tools"):
+    packages.append("libav-tools")
+
+  if package_exists("libvulkan-dev"):
+    packages.append("libvulkan-dev")
+
+  if package_exists("libinput-dev"):
+    packages.append("libinput-dev")
+
+  if package_exists("snapcraft"):
+    packages.append("snapcraft")
+
+  # Cross-toolchain strip is needed for building the sysroots.
+  if package_exists("binutils-arm-linux-gnueabihf"):
+    packages.append("binutils-arm-linux-gnueabihf")
+  if package_exists("binutils-aarch64-linux-gnu"):
+    packages.append("binutils-aarch64-linux-gnu")
+  if package_exists("binutils-mipsel-linux-gnu"):
+    packages.append("binutils-mipsel-linux-gnu")
+  if package_exists("binutils-mips64el-linux-gnuabi64"):
+    packages.append("binutils-mips64el-linux-gnuabi64")
+
+  # 64-bit systems need a minimum set of 32-bit compat packages for the
+  # pre-built NaCl binaries.
+  if "ELF 64-bit" in subprocess.check_output(["file", "-L", "/sbin/init"],
+                                             text=True):
+    packages.extend(["libc6-i386", "lib32stdc++6"])
+
+    # lib32gcc-s1 used to be called lib32gcc1 in older distros.
+    if package_exists("lib32gcc-s1"):
+      packages.append("lib32gcc-s1")
+    elif package_exists("lib32gcc1"):
+      packages.append("lib32gcc1")
+
+  return packages
+
+
+# List of required run-time libraries
+def lib_list():
+  packages = [
+      "lib32z1",
+      "libasound2",
+      "libatk1.0-0",
+      "libatspi2.0-0",
+      "libc6",
+      "libcairo2",
+      "libcap2",
+      "libcgi-session-perl",
+      "libcups2",
+      "libdrm2",
+      "libegl1",
+      "libevdev2",
+      "libexpat1",
+      "libfontconfig1",
+      "libfreetype6",
+      "libgbm1",
+      "libglib2.0-0",
+      "libgl1",
+      "libgtk-3-0",
+      "libncurses5",
+      "libpam0g",
+      "libpango-1.0-0",
+      "libpangocairo-1.0-0",
+      "libpci3",
+      "libpcre3",
+      "libpixman-1-0",
+      "libspeechd2",
+      "libstdc++6",
+      "libsqlite3-0",
+      "libuuid1",
+      "libwayland-egl1",
+      "libwayland-egl1-mesa",
+      "libx11-6",
+      "libx11-xcb1",
+      "libxau6",
+      "libxcb1",
+      "libxcomposite1",
+      "libxcursor1",
+      "libxdamage1",
+      "libxdmcp6",
+      "libxext6",
+      "libxfixes3",
+      "libxi6",
+      "libxinerama1",
+      "libxrandr2",
+      "libxrender1",
+      "libxtst6",
+      "x11-utils",
+      "xvfb",
+      "zlib1g",
+  ]
+
+  # Run-time libraries required by chromeos only
+  packages += [
+      "libpulse0",
+      "libbz2-1.0",
+  ]
+
+  if package_exists("libffi8"):
+    packages.append("libffi8")
+  elif package_exists("libffi7"):
+    packages.append("libffi7")
+  elif package_exists("libffi6"):
+    packages.append("libffi6")
+
+  if package_exists("libpng16-16"):
+    packages.append("libpng16-16")
+  else:
+    packages.append("libpng12-0")
+
+  if package_exists("libnspr4"):
+    packages.extend(["libnspr4", "libnss3"])
+  else:
+    packages.extend(["libnspr4-0d", "libnss3-1d"])
+
+  if package_exists("appmenu-gtk"):
+    packages.append("appmenu-gtk")
+  if package_exists("libgnome-keyring0"):
+    packages.append("libgnome-keyring0")
+  if package_exists("libgnome-keyring-dev"):
+    packages.append("libgnome-keyring-dev")
+  if package_exists("libvulkan1"):
+    packages.append("libvulkan1")
+  if package_exists("libinput10"):
+    packages.append("libinput10")
+
+  return packages
+
+
+def lib32_list(options):
+  if not options.lib32:
+    print("Skipping 32-bit libraries.", file=sys.stderr)
+    return []
+  print("Including 32-bit libraries.", file=sys.stderr)
+
+  packages = [
+      # 32-bit libraries needed for a 32-bit build
+      # includes some 32-bit libraries required by the Android SDK
+      # See https://developer.android.com/sdk/installing/index.html?pkg=tools
+      "libasound2:i386",
+      "libatk-bridge2.0-0:i386",
+      "libatk1.0-0:i386",
+      "libatspi2.0-0:i386",
+      "libdbus-1-3:i386",
+      "libegl1:i386",
+      "libgl1:i386",
+      "libglib2.0-0:i386",
+      "libncurses5:i386",
+      "libnss3:i386",
+      "libpango-1.0-0:i386",
+      "libpangocairo-1.0-0:i386",
+      "libstdc++6:i386",
+      "libwayland-egl1:i386",
+      "libx11-xcb1:i386",
+      "libxcomposite1:i386",
+      "libxdamage1:i386",
+      "libxkbcommon0:i386",
+      "libxrandr2:i386",
+      "libxtst6:i386",
+      "zlib1g:i386",
+      # 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf
+      "linux-libc-dev:i386",
+      "libpci3:i386",
+  ]
+
+  # When cross building for arm/Android on 64-bit systems the host binaries
+  # that are part of v8 need to be compiled with -m32 which means
+  # that basic multilib support is needed.
+  if "ELF 64-bit" in subprocess.check_output(["file", "-L", "/sbin/init"],
+                                             text=True):
+    # gcc-multilib conflicts with the arm cross compiler but
+    # g++-X.Y-multilib gives us the 32-bit support that we need. Find out the
+    # appropriate value of X and Y by seeing what version the current
+    # distribution's g++-multilib package depends on.
+    lines = subprocess.check_output(
+        ["apt-cache", "depends", "g++-multilib", "--important"],
+        text=True).splitlines()
+    pattern = re.compile(r"g\+\+-[0-9.]+-multilib")
+    packages.extend(line.strip() for line in lines if pattern.match(line))
+
+  return packages
+
+
+# Packages that have been removed from this script. Regardless of configuration
+# or options passed to this script, whenever a package is removed, it should be
+# added here.
+def backwards_compatible_list(options):
+  if not options.backwards_compatible:
+    print("Skipping backwards compatible packages.", file=sys.stderr)
+    return []
+  print("Including backwards compatible packages.", file=sys.stderr)
+
+  packages = [
+      "7za",
+      "fonts-indic",
+      "fonts-ipafont",
+      "fonts-stix",
+      "fonts-thai-tlwg",
+      "fonts-tlwg-garuda",
+      "g++",
+      "g++-4.8-multilib-arm-linux-gnueabihf",
+      "gcc-4.8-multilib-arm-linux-gnueabihf",
+      "g++-9-multilib-arm-linux-gnueabihf",
+      "gcc-9-multilib-arm-linux-gnueabihf",
+      "gcc-arm-linux-gnueabihf",
+      "g++-10-multilib-arm-linux-gnueabihf",
+      "gcc-10-multilib-arm-linux-gnueabihf",
+      "g++-10-arm-linux-gnueabihf",
+      "gcc-10-arm-linux-gnueabihf",
+      "git-svn",
+      "language-pack-da",
+      "language-pack-fr",
+      "language-pack-he",
+      "language-pack-zh-hant",
+      "libappindicator-dev",
+      "libappindicator1",
+      "libappindicator3-1",
+      "libappindicator3-dev",
+      "libdconf-dev",
+      "libdconf1",
+      "libdconf1:i386",
+      "libexif-dev",
+      "libexif12",
+      "libexif12:i386",
+      "libgbm-dev",
+      "libgbm-dev-lts-trusty",
+      "libgbm-dev-lts-xenial",
+      "libgconf-2-4:i386",
+      "libgconf2-dev",
+      "libgl1-mesa-dev",
+      "libgl1-mesa-dev-lts-trusty",
+      "libgl1-mesa-dev-lts-xenial",
+      "libgl1-mesa-glx:i386",
+      "libgl1-mesa-glx-lts-trusty:i386",
+      "libgl1-mesa-glx-lts-xenial:i386",
+      "libgles2-mesa-dev",
+      "libgles2-mesa-dev-lts-trusty",
+      "libgles2-mesa-dev-lts-xenial",
+      "libgtk-3-0:i386",
+      "libgtk2.0-0",
+      "libgtk2.0-0:i386",
+      "libgtk2.0-dev",
+      "mesa-common-dev",
+      "mesa-common-dev-lts-trusty",
+      "mesa-common-dev-lts-xenial",
+      "msttcorefonts",
+      "python-dev",
+      "python-setuptools",
+      "ttf-dejavu-core",
+      "ttf-indic-fonts",
+      "ttf-kochi-gothic",
+      "ttf-kochi-mincho",
+      "ttf-mscorefonts-installer",
+      "xfonts-mathml",
+  ]
+
+  if package_exists("python-is-python2"):
+    packages.extend(["python-is-python2", "python2-dev"])
+  else:
+    packages.append("python")
+
+  if package_exists("python-crypto"):
+    packages.append("python-crypto")
+
+  if package_exists("python-numpy"):
+    packages.append("python-numpy")
+
+  if package_exists("python-openssl"):
+    packages.append("python-openssl")
+
+  if package_exists("python-psutil"):
+    packages.append("python-psutil")
+
+  if package_exists("python-yaml"):
+    packages.append("python-yaml")
+
+  if package_exists("apache2.2-bin"):
+    packages.append("apache2.2-bin")
+  else:
+    packages.append("apache2-bin")
+
+  php_versions = [
+      ("php8.1-cgi", "libapache2-mod-php8.1"),
+      ("php8.0-cgi", "libapache2-mod-php8.0"),
+      ("php7.4-cgi", "libapache2-mod-php7.4"),
+      ("php7.3-cgi", "libapache2-mod-php7.3"),
+      ("php7.2-cgi", "libapache2-mod-php7.2"),
+      ("php7.1-cgi", "libapache2-mod-php7.1"),
+      ("php7.0-cgi", "libapache2-mod-php7.0"),
+      ("php5-cgi", "libapache2-mod-php5"),
+  ]
+
+  for php_cgi, mod_php in php_versions:
+    if package_exists(php_cgi):
+      packages.extend([php_cgi, mod_php])
+      break
+
+  return [package for package in packages if package_exists(package)]
+
+
+def arm_list(options):
+  if not options.arm:
+    print("Skipping ARM cross toolchain.", file=sys.stderr)
+    return []
+  print("Including ARM cross toolchain.", file=sys.stderr)
+
+  # arm cross toolchain packages needed to build chrome on armhf
+  packages = [
+      "libc6-dev-armhf-cross",
+      "linux-libc-dev-armhf-cross",
+      "g++-arm-linux-gnueabihf",
+  ]
+
+  # Work around for dependency issue Ubuntu: http://crbug.com/435056
+  if distro_codename() == "bionic":
+    packages.extend([
+        "g++-5-multilib-arm-linux-gnueabihf",
+        "gcc-5-multilib-arm-linux-gnueabihf",
+        "gcc-arm-linux-gnueabihf",
+    ])
+  elif distro_codename() == "focal":
+    packages.extend([
+        "g++-10-multilib-arm-linux-gnueabihf",
+        "gcc-10-multilib-arm-linux-gnueabihf",
+        "gcc-arm-linux-gnueabihf",
+    ])
+  elif distro_codename() == "jammy":
+    packages.extend([
+        "gcc-arm-linux-gnueabihf",
+        "g++-11-arm-linux-gnueabihf",
+        "gcc-11-arm-linux-gnueabihf",
+    ])
+
+  return packages
+
+
+def nacl_list(options):
+  if not options.nacl:
+    print("Skipping NaCl, NaCl toolchain, NaCl ports dependencies.",
+          file=sys.stderr)
+    return []
+  print("Including NaCl, NaCl toolchain, NaCl ports dependencies.",
+        file=sys.stderr)
+
+  packages = [
+      "g++-mingw-w64-i686",
+      "lib32z1-dev",
+      "libasound2:i386",
+      "libcap2:i386",
+      "libelf-dev:i386",
+      "libfontconfig1:i386",
+      "libglib2.0-0:i386",
+      "libgpm2:i386",
+      "libncurses5:i386",
+      "lib32ncurses5-dev",
+      "libnss3:i386",
+      "libpango-1.0-0:i386",
+      "libssl-dev:i386",
+      "libtinfo-dev",
+      "libtinfo-dev:i386",
+      "libtool",
+      "libuuid1:i386",
+      "libxcomposite1:i386",
+      "libxcursor1:i386",
+      "libxdamage1:i386",
+      "libxi6:i386",
+      "libxrandr2:i386",
+      "libxss1:i386",
+      "libxtst6:i386",
+      "texinfo",
+      "xvfb",
+      # Packages to build NaCl, its toolchains, and its ports.
+      "ant",
+      "autoconf",
+      "bison",
+      "cmake",
+      "gawk",
+      "intltool",
+      "xutils-dev",
+      "xsltproc",
+  ]
+
+  # Some package names have changed over time
+  if package_exists("libssl-dev"):
+    packages.append("libssl-dev:i386")
+  elif package_exists("libssl1.1"):
+    packages.append("libssl1.1:i386")
+  elif package_exists("libssl1.0.2"):
+    packages.append("libssl1.0.2:i386")
+  else:
+    packages.append("libssl1.0.0:i386")
+
+  if package_exists("libtinfo5"):
+    packages.append("libtinfo5")
+
+  if package_exists("libudev1"):
+    packages.append("libudev1:i386")
+  else:
+    packages.append("libudev0:i386")
+
+  return packages
+
+
+# Debian is in the process of transitioning to automatic debug packages, which
+# have the -dbgsym suffix (https://wiki.debian.org/AutomaticDebugPackages).
+# Untransitioned packages have the -dbg suffix.  And on some systems, neither
+# will be available, so exclude the ones that are missing.
+def dbg_package_name(package):
+  if package_exists(f"{package}-dbgsym"):
+    return [f"{package}-dbgsym"]
+  if package_exists(f"{package}-dbg"):
+    return [f"{package}-dbg"]
+  return []
+
+
+def dbg_list(options):
+  if not options.syms:
+    print("Skipping debugging symbols.", file=sys.stderr)
+    return []
+  print("Including debugging symbols.", file=sys.stderr)
+
+  packages = [
+      dbg_package_name(package) for packages in lib_list()
+      for package in packages
+  ]
+
+  # Debugging symbols packages not following common naming scheme
+  if not dbg_package_name("libstdc++6"):
+    for version in ["8", "7", "6", "5", "4.9", "4.8", "4.7", "4.6"]:
+      if package_exists(f"libstdc++6-{version}-dbg"):
+        packages.append(f"libstdc++6-{version}-dbg")
+        break
+
+  if not dbg_package_name("libatk1.0-0"):
+    packages.extend(dbg_package_name("libatk1.0"))
+
+  if not dbg_package_name("libpango-1.0-0"):
+    packages.extend(dbg_package_name("libpango1.0-dev"))
+
+  return packages
+
+
+def package_list(options):
+  packages = (dev_list() + lib_list() + dbg_list(options) +
+              lib32_list(options) + arm_list(options) + nacl_list(options) +
+              backwards_compatible_list(options))
+
+  # Sort all the :i386 packages to the front, to avoid confusing dpkg-query
+  # (https://crbug.com/446172).
+  return sorted(set(packages), key=lambda x: (not x.endswith(":i386"), x))
+
+
+def missing_packages(packages):
+  try:
+    subprocess.run(
+        ["dpkg-query", "-W", "-f", " "] + packages,
+        check=True,
+        capture_output=True,
+        text=True,
+    )
+    return []
+  except subprocess.CalledProcessError as e:
+    return [line.split(" ")[-1] for line in e.stderr.strip().splitlines()]
+
+
+def package_is_installable(package):
+  result = subprocess.run(["apt-cache", "show", package],
+                          capture_output=True,
+                          text=True)
+  return result.returncode == 0
+
+
+def quick_check(options):
+  if not options.quick_check:
+    return
+
+  missing = missing_packages(package_list(options))
+  if not missing:
+    sys.exit(0)
+
+  not_installed = []
+  unknown = []
+  for p in missing:
+    if package_is_installable(p):
+      not_installed.append(p)
+    else:
+      unknown.append(p)
+
+  if not_installed:
+    print("WARNING: The following packages are not installed:", file=sys.stderr)
+    print(" ".join(not_installed), file=sys.stderr)
+
+  if unknown:
+    print("WARNING: The following packages are unknown to your system",
+          file=sys.stderr)
+    print("(maybe missing a repo or need to 'sudo apt-get update'):",
+          file=sys.stderr)
+    print(" ".join(unknown), file=sys.stderr)
+
+  sys.exit(1)
+
+
+def find_missing_packages(options):
+  print("Finding missing packages...", file=sys.stderr)
+
+  packages = package_list(options)
+  packages_str = " ".join(packages)
+  print(f"Packages required: {packages_str}", file=sys.stderr)
+
+  query_cmd = ["apt-get", "--just-print", "install"] + packages
+
+  cmd_output = subprocess.check_output(query_cmd,
+                                       env=os.environ | {
+                                           "LANGUAGE": "en",
+                                           "LANG": "C"
+                                       },
+                                       text=True)
+  lines = [line.strip() for line in cmd_output.splitlines()]
+
+  install = []
+  for pattern in (
+      "The following NEW packages will be installed:",
+      "The following packages will be upgraded:",
+  ):
+    if pattern in lines:
+      install += lines[lines.index(pattern) + 1].split(" ")
+
+  return install
+
+
+def install_packages(options):
+  try:
+    packages = find_missing_packages(options)
+    if packages:
+      quiet = ["-qq", "--assume-yes"] if options.no_prompt else []
+      subprocess.check_call(["sudo", "apt-get", "install"] + quiet + packages)
+      print(file=sys.stderr)
+    else:
+      print("No missing packages, and the packages are up to date.",
+            file=sys.stderr)
+
+  except subprocess.CalledProcessError as e:
+    # An apt-get exit status of 100 indicates that a real error has occurred.
+    print("`apt-get --just-print install ...` failed", file=sys.stderr)
+    print("It produced the following output:", file=sys.stderr)
+    print(e.output, file=sys.stderr)
+    print(file=sys.stderr)
+    print("You will have to install the above packages yourself.",
+          file=sys.stderr)
+    print(file=sys.stderr)
+    sys.exit(100)
+
+
+# Install the Chrome OS default fonts. This must go after running
+# apt-get, since install-chromeos-fonts depends on curl.
+def install_chromeos_fonts(options):
+  if not options.chromeos_fonts:
+    print("Skipping installation of Chrome OS fonts.", file=sys.stderr)
+    return
+  print("Installing Chrome OS fonts.", file=sys.stderr)
+
+  dir = os.path.abspath(os.path.dirname(__file__))
+
+  try:
+    subprocess.check_call(
+        ["sudo",
+         os.path.join(dir, "linux", "install-chromeos-fonts.py")])
+  except subprocess.CalledProcessError:
+    print("ERROR: The installation of the Chrome OS default fonts failed.",
+          file=sys.stderr)
+    if subprocess.check_output(["stat", "-f", "-c", "%T", dir],
+                               text=True).startswith("nfs"):
+      print(
+          "The reason is that your repo is installed on a remote file system.",
+          file=sys.stderr)
+    else:
+      print(
+          "This is expected if your repo is installed on a remote file system.",
+          file=sys.stderr)
+
+    print("It is recommended to install your repo on a local file system.",
+          file=sys.stderr)
+    print("You can skip the installation of the Chrome OS default fonts with",
+          file=sys.stderr)
+    print("the command line option: --no-chromeos-fonts.", file=sys.stderr)
+    sys.exit(1)
+
+
+def install_locales():
+  print("Installing locales.", file=sys.stderr)
+  CHROMIUM_LOCALES = [
+      "da_DK.UTF-8", "fr_FR.UTF-8", "he_IL.UTF-8", "zh_TW.UTF-8"
+  ]
+  LOCALE_GEN = "/etc/locale.gen"
+  if os.path.exists(LOCALE_GEN):
+    old_locale_gen = open(LOCALE_GEN).read()
+    for locale in CHROMIUM_LOCALES:
+      subprocess.check_call(
+          ["sudo", "sed", "-i", f"s/^# {locale}/{locale}/", LOCALE_GEN])
+
+    # Regenerating locales can take a while, so only do it if we need to.
+    locale_gen = open(LOCALE_GEN).read()
+    if locale_gen != old_locale_gen:
+      subprocess.check_call(["sudo", "locale-gen"])
+    else:
+      print("Locales already up-to-date.", file=sys.stderr)
+  else:
+    for locale in CHROMIUM_LOCALES:
+      subprocess.check_call(["sudo", "locale-gen", locale])
+
+
+def main():
+  options = parse_args(sys.argv[1:])
+  check_lsb_release()
+  check_distro(options)
+  check_architecture()
+  quick_check(options)
+  check_root()
+  apt_update(options)
+  install_packages(options)
+  install_chromeos_fonts(options)
+  install_locales()
+  return 0
+
+
+if __name__ == "__main__":
+  sys.exit(main())
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index de4081dc..7ad84c6 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -4,809 +4,4 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Script to install everything needed to build chromium (well, ideally, anyway)
-# including items requiring sudo privileges.
-# See https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md
-# and https://chromium.googlesource.com/chromium/src/+/HEAD/docs/android_build_instructions.md
-
-usage() {
-  echo "Usage: $0 [--options]"
-  echo "Options:"
-  echo "--[no-]syms: enable or disable installation of debugging symbols"
-  echo "--lib32: enable installation of 32-bit libraries, e.g. for V8 snapshot"
-  echo "--[no-]android: enable or disable installation of android dependencies"
-  echo "--[no-]arm: enable or disable installation of arm cross toolchain"
-  echo "--[no-]chromeos-fonts: enable or disable installation of Chrome OS"\
-       "fonts"
-  echo "--[no-]nacl: enable or disable installation of prerequisites for"\
-       "building standalone NaCl and all its toolchains"
-  echo "--[no-]backwards-compatible: enable or disable installation of packages
-        that are no longer currently needed and have been removed from this
-        script.  Useful for bisection."
-  echo "--no-prompt: silently select standard options/defaults"
-  echo "--quick-check: quickly try to determine if dependencies are installed"
-  echo "               (this avoids interactive prompts and sudo commands,"
-  echo "               so might not be 100% accurate)"
-  echo "--unsupported: attempt installation even on unsupported systems"
-  echo "Script will prompt interactively if options not given."
-  exit 1
-}
-
-# Build list of apt packages in dpkg --get-selections format.
-build_apt_package_list() {
-  echo "Building apt package list." >&2
-  apt-cache dumpavail | \
-    python3 -c 'import re,sys; \
-o = sys.stdin.read(); \
-p = {"i386": ":i386"}; \
-f = re.M | re.S; \
-r = re.compile(r"^Package: (.+?)$.+?^Architecture: (.+?)$", f); \
-m = ["%s%s" % (x, p.get(y, "")) for x, y in re.findall(r, o)]; \
-print("\n".join(m))'
-}
-
-# Checks whether a particular package is available in the repos.
-# Uses pre-formatted ${apt_package_list}.
-# USAGE: $ package_exists <package name>
-package_exists() {
-  if [ -z "${apt_package_list}" ]; then
-    echo "Call build_apt_package_list() prior to calling package_exists()" >&2
-    apt_package_list=$(build_apt_package_list)
-  fi
-  # `grep` takes a regex string, so the +'s in package names, e.g. "libstdc++",
-  # need to be escaped.
-  local escaped="$(echo $1 | sed 's/[\~\+\.\:-]/\\&/g')"
-  [ ! -z "$(grep "^${escaped}$" <<< "${apt_package_list}")" ]
-}
-
-do_inst_arm=0
-do_inst_nacl=0
-do_inst_android=0
-
-while [ "$1" != "" ]
-do
-  case "$1" in
-  --syms)                    do_inst_syms=1;;
-  --no-syms)                 do_inst_syms=0;;
-  --lib32)                   do_inst_lib32=1;;
-  --android)                 do_inst_android=1;;
-  --no-android)              do_inst_android=0;;
-  --arm)                     do_inst_arm=1;;
-  --no-arm)                  do_inst_arm=0;;
-  --chromeos-fonts)          do_inst_chromeos_fonts=1;;
-  --no-chromeos-fonts)       do_inst_chromeos_fonts=0;;
-  --nacl)                    do_inst_nacl=1;;
-  --no-nacl)                 do_inst_nacl=0;;
-  --backwards-compatible)    do_inst_backwards_compatible=1;;
-  --no-backwards-compatible) do_inst_backwards_compatible=0;;
-  --add-cross-tool-repo)     add_cross_tool_repo=1;;
-  --no-prompt)               do_default=1
-                             do_quietly="-qq --assume-yes"
-    ;;
-  --quick-check)             do_quick_check=1;;
-  --unsupported)             do_unsupported=1;;
-  *) usage;;
-  esac
-  shift
-done
-
-if [ "$do_inst_arm" = "1" ]; then
-  do_inst_lib32=1
-fi
-
-if [ "$do_inst_android" = "1" ]; then
-  do_inst_lib32=1
-fi
-
-# Check for lsb_release command in $PATH
-if ! which lsb_release > /dev/null; then
-  echo "ERROR: lsb_release not found in \$PATH" >&2
-  echo "try: sudo apt-get install lsb-release" >&2
-  exit 1;
-fi
-
-distro_codename=$(lsb_release --codename --short)
-distro_id=$(lsb_release --id --short)
-supported_codenames="(bionic|focal|jammy)"
-supported_ids="(Debian)"
-if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
-  if [[ ! $distro_codename =~ $supported_codenames &&
-        ! $distro_id =~ $supported_ids ]]; then
-    echo -e "WARNING: The following distributions are supported,
-    but distributions not in the list below can also try to install
-    dependencies by passing the `--unsupported` parameter\n" \
-      "\tUbuntu 18.04 LTS (bionic with EoL April 2028)\n" \
-      "\tUbuntu 20.04 LTS (focal with EoL April 2030)\n" \
-      "\tUbuntu 22.04 LTS (jammy with EoL April 2032)\n" \
-      "\tDebian 10 (buster) or later" >&2
-    exit 1
-  fi
-
-# Check system architecture
-  if ! uname -m | egrep -q "i686|x86_64"; then
-    echo "Only x86 architectures are currently supported" >&2
-    exit
-  fi
-fi
-
-if [ "x$(id -u)" != x0 ] && [ 0 -eq "${do_quick_check-0}" ]; then
-  echo "Running as non-root user."
-  echo "You might have to enter your password one or more times for 'sudo'."
-  echo
-fi
-
-if [ 0 -eq "${do_quick_check-0}" ] ; then
-  if [ "$do_inst_lib32" = "1" ] || [ "$do_inst_nacl" = "1" ]; then
-    sudo dpkg --add-architecture i386
-  fi
-  sudo apt-get update
-fi
-
-# Populate ${apt_package_list} for package_exists() parsing.
-apt_package_list=$(build_apt_package_list)
-
-# Packages needed for chromeos only
-chromeos_dev_list="libbluetooth-dev libxkbcommon-dev mesa-common-dev zstd"
-
-if package_exists realpath; then
-  chromeos_dev_list="${chromeos_dev_list} realpath"
-fi
-
-# Packages needed for development
-dev_list="\
-  binutils
-  bison
-  bzip2
-  cdbs
-  curl
-  dbus-x11
-  dpkg-dev
-  elfutils
-  devscripts
-  fakeroot
-  flex
-  git-core
-  gperf
-  libasound2-dev
-  libatspi2.0-dev
-  libbrlapi-dev
-  libbz2-dev
-  libcairo2-dev
-  libcap-dev
-  libc6-dev
-  libcups2-dev
-  libcurl4-gnutls-dev
-  libdrm-dev
-  libelf-dev
-  libevdev-dev
-  libffi-dev
-  libgbm-dev
-  libglib2.0-dev
-  libglu1-mesa-dev
-  libgtk-3-dev
-  libkrb5-dev
-  libnspr4-dev
-  libnss3-dev
-  libpam0g-dev
-  libpci-dev
-  libpulse-dev
-  libsctp-dev
-  libspeechd-dev
-  libsqlite3-dev
-  libssl-dev
-  libsystemd-dev
-  libudev-dev
-  libva-dev
-  libwww-perl
-  libxshmfence-dev
-  libxslt1-dev
-  libxss-dev
-  libxt-dev
-  libxtst-dev
-  lighttpd
-  locales
-  openbox
-  p7zip
-  patch
-  perl
-  pkg-config
-  rpm
-  ruby
-  subversion
-  uuid-dev
-  wdiff
-  x11-utils
-  xcompmgr
-  xz-utils
-  zip
-  $chromeos_dev_list
-"
-
-# 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
-# NaCl binaries.
-if file -L /sbin/init | grep -q 'ELF 64-bit'; then
-  dev_list="${dev_list} libc6-i386 lib32stdc++6"
-
-  # lib32gcc-s1 used to be called lib32gcc1 in older distros.
-  if package_exists lib32gcc-s1; then
-    dev_list="${dev_list} lib32gcc-s1"
-  elif package_exists lib32gcc1; then
-    dev_list="${dev_list} lib32gcc1"
-  fi
-fi
-
-# Run-time libraries required by chromeos only
-chromeos_lib_list="libpulse0 libbz2-1.0"
-
-# List of required run-time libraries
-common_lib_list="\
-  lib32z1
-  libasound2
-  libatk1.0-0
-  libatspi2.0-0
-  libc6
-  libcairo2
-  libcap2
-  libcgi-session-perl
-  libcups2
-  libdrm2
-  libegl1
-  libevdev2
-  libexpat1
-  libfontconfig1
-  libfreetype6
-  libgbm1
-  libglib2.0-0
-  libgl1
-  libgtk-3-0
-  libncurses5
-  libpam0g
-  libpango-1.0-0
-  libpangocairo-1.0-0
-  libpci3
-  libpcre3
-  libpixman-1-0
-  libspeechd2
-  libstdc++6
-  libsqlite3-0
-  libuuid1
-  libwayland-egl1
-  libwayland-egl1-mesa
-  libx11-6
-  libx11-xcb1
-  libxau6
-  libxcb1
-  libxcomposite1
-  libxcursor1
-  libxdamage1
-  libxdmcp6
-  libxext6
-  libxfixes3
-  libxi6
-  libxinerama1
-  libxrandr2
-  libxrender1
-  libxtst6
-  x11-utils
-  xvfb
-  zlib1g
-"
-
-if package_exists libffi8; then
-  common_lib_list="${common_lib_list} libffi8"
-elif package_exists libffi7; then
-  common_lib_list="${common_lib_list} libffi7"
-elif package_exists libffi6; then
-  common_lib_list="${common_lib_list} libffi6"
-fi
-
-# Full list of required run-time libraries
-lib_list="\
-  $common_lib_list
-  $chromeos_lib_list
-"
-
-# 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf
-lib32_list="linux-libc-dev:i386 libpci3:i386"
-
-# 32-bit libraries needed for a 32-bit build
-# includes some 32-bit libraries required by the Android SDK
-# See https://developer.android.com/sdk/installing/index.html?pkg=tools
-lib32_list="$lib32_list
-  libasound2:i386
-  libatk-bridge2.0-0:i386
-  libatk1.0-0:i386
-  libatspi2.0-0:i386
-  libdbus-1-3:i386
-  libegl1:i386
-  libgl1:i386
-  libglib2.0-0:i386
-  libncurses5:i386
-  libnss3:i386
-  libpango-1.0-0:i386
-  libpangocairo-1.0-0:i386
-  libstdc++6:i386
-  libwayland-egl1:i386
-  libx11-xcb1:i386
-  libxcomposite1:i386
-  libxdamage1:i386
-  libxkbcommon0:i386
-  libxrandr2:i386
-  libxtst6:i386
-  zlib1g:i386
-"
-
-# Packages that have been removed from this script.  Regardless of configuration
-# or options passed to this script, whenever a package is removed, it should be
-# added here.
-backwards_compatible_list="\
-  7za
-  fonts-indic
-  fonts-ipafont
-  fonts-stix
-  fonts-thai-tlwg
-  fonts-tlwg-garuda
-  g++
-  g++-4.8-multilib-arm-linux-gnueabihf
-  gcc-4.8-multilib-arm-linux-gnueabihf
-  g++-9-multilib-arm-linux-gnueabihf
-  gcc-9-multilib-arm-linux-gnueabihf
-  gcc-arm-linux-gnueabihf
-  g++-10-multilib-arm-linux-gnueabihf
-  gcc-10-multilib-arm-linux-gnueabihf
-  g++-10-arm-linux-gnueabihf
-  gcc-10-arm-linux-gnueabihf
-  git-svn
-  language-pack-da
-  language-pack-fr
-  language-pack-he
-  language-pack-zh-hant
-  libappindicator-dev
-  libappindicator1
-  libappindicator3-1
-  libappindicator3-dev
-  libdconf-dev
-  libdconf1
-  libdconf1:i386
-  libexif-dev
-  libexif12
-  libexif12:i386
-  libgbm-dev
-  libgbm-dev-lts-trusty
-  libgbm-dev-lts-xenial
-  libgconf-2-4:i386
-  libgconf2-dev
-  libgl1-mesa-dev
-  libgl1-mesa-dev-lts-trusty
-  libgl1-mesa-dev-lts-xenial
-  libgl1-mesa-glx:i386
-  libgl1-mesa-glx-lts-trusty:i386
-  libgl1-mesa-glx-lts-xenial:i386
-  libgles2-mesa-dev
-  libgles2-mesa-dev-lts-trusty
-  libgles2-mesa-dev-lts-xenial
-  libgtk-3-0:i386
-  libgtk2.0-0
-  libgtk2.0-0:i386
-  libgtk2.0-dev
-  mesa-common-dev
-  mesa-common-dev-lts-trusty
-  mesa-common-dev-lts-xenial
-  msttcorefonts
-  python-dev
-  python-setuptools
-  ttf-dejavu-core
-  ttf-indic-fonts
-  ttf-kochi-gothic
-  ttf-kochi-mincho
-  ttf-mscorefonts-installer
-  xfonts-mathml
-"
-
-if package_exists python-is-python2; then
-  backwards_compatible_list="${backwards_compatible_list} python-is-python2 python2-dev"
-else
-  backwards_compatible_list="${backwards_compatible_list} python"
-fi
-
-if package_exists python-crypto; then
-  backwards_compatible_list="${backwards_compatible_list} python-crypto"
-fi
-
-if package_exists python-numpy; then
-  backwards_compatible_list="${backwards_compatible_list} python-numpy"
-fi
-
-if package_exists python-openssl; then
-  backwards_compatible_list="${backwards_compatible_list} python-openssl"
-fi
-
-if package_exists python-psutil; then
-  backwards_compatible_list="${backwards_compatible_list} python-psutil"
-fi
-
-if package_exists python-yaml; then
-  backwards_compatible_list="${backwards_compatible_list} python-yaml"
-fi
-if package_exists apache2.2-bin; then
-  backwards_compatible_list="${backwards_compatible_list} apache2.2-bin"
-else
-  backwards_compatible_list="${backwards_compatible_list} apache2-bin"
-fi
-if package_exists php8.1-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php8.1-cgi libapache2-mod-php8.1"
-elif package_exists php8.0-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php8.0-cgi libapache2-mod-php8.0"
-elif package_exists php7.4-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php7.4-cgi libapache2-mod-php7.4"
-elif package_exists php7.3-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php7.3-cgi libapache2-mod-php7.3"
-elif package_exists php7.2-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php7.2-cgi libapache2-mod-php7.2"
-elif package_exists php7.1-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php7.1-cgi libapache2-mod-php7.1"
-elif package_exists php7.0-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php7.0-cgi libapache2-mod-php7.0"
-elif package_exists php8.0-cgi; then
-  backwards_compatible_list="${backwards_compatible_list} php8.0-cgi libapache2-mod-php8.0"
-else
-  backwards_compatible_list="${backwards_compatible_list} php5-cgi libapache2-mod-php5"
-fi
-
-# arm cross toolchain packages needed to build chrome on armhf
-arm_list="libc6-dev-armhf-cross
-          linux-libc-dev-armhf-cross
-          g++-arm-linux-gnueabihf"
-
-# Work around for dependency issue Ubuntu: http://crbug.com/435056
-case $distro_codename in
-  bionic)
-    arm_list+=" g++-5-multilib-arm-linux-gnueabihf
-                gcc-5-multilib-arm-linux-gnueabihf
-                gcc-arm-linux-gnueabihf"
-    ;;
-  focal)
-    arm_list+=" g++-10-multilib-arm-linux-gnueabihf
-                gcc-10-multilib-arm-linux-gnueabihf
-                gcc-arm-linux-gnueabihf"
-    ;;
-  jammy)
-    arm_list+=" gcc-arm-linux-gnueabihf
-                g++-11-arm-linux-gnueabihf
-                gcc-11-arm-linux-gnueabihf"
-    ;;
-esac
-
-# Packages to build NaCl, its toolchains, and its ports.
-naclports_list="ant autoconf bison cmake gawk intltool xutils-dev xsltproc"
-nacl_list="\
-  g++-mingw-w64-i686
-  lib32z1-dev
-  libasound2:i386
-  libcap2:i386
-  libelf-dev:i386
-  libfontconfig1:i386
-  libglib2.0-0:i386
-  libgpm2:i386
-  libncurses5:i386
-  lib32ncurses5-dev
-  libnss3:i386
-  libpango-1.0-0:i386
-  libssl-dev:i386
-  libtinfo-dev
-  libtinfo-dev:i386
-  libtool
-  libuuid1:i386
-  libxcomposite1:i386
-  libxcursor1:i386
-  libxdamage1:i386
-  libxi6:i386
-  libxrandr2:i386
-  libxss1:i386
-  libxtst6:i386
-  texinfo
-  xvfb
-  ${naclports_list}
-"
-
-# Some package names have changed over time
-if package_exists libssl-dev; then
-  nacl_list="${nacl_list} libssl-dev:i386"
-elif package_exists libssl1.1; then
-  nacl_list="${nacl_list} libssl1.1:i386"
-elif package_exists libssl1.0.2; then
-  nacl_list="${nacl_list} libssl1.0.2:i386"
-else
-  nacl_list="${nacl_list} libssl1.0.0:i386"
-fi
-if package_exists libtinfo5; then
-  nacl_list="${nacl_list} libtinfo5"
-fi
-if package_exists libpng16-16; then
-  lib_list="${lib_list} libpng16-16"
-else
-  lib_list="${lib_list} libpng12-0"
-fi
-if package_exists libnspr4; then
-  lib_list="${lib_list} libnspr4 libnss3"
-else
-  lib_list="${lib_list} libnspr4-0d libnss3-1d"
-fi
-if package_exists libjpeg-dev; then
-  dev_list="${dev_list} libjpeg-dev"
-else
-  dev_list="${dev_list} libjpeg62-dev"
-fi
-if package_exists libudev1; then
-  dev_list="${dev_list} libudev1"
-  nacl_list="${nacl_list} libudev1:i386"
-else
-  dev_list="${dev_list} libudev0"
-  nacl_list="${nacl_list} libudev0:i386"
-fi
-if package_exists libbrlapi0.8; then
-  dev_list="${dev_list} libbrlapi0.8"
-elif package_exists libbrlapi0.7; then
-  dev_list="${dev_list} libbrlapi0.7"
-elif package_exists libbrlapi0.6; then
-  dev_list="${dev_list} libbrlapi0.6"
-else
-  dev_list="${dev_list} libbrlapi0.5"
-fi
-if package_exists libav-tools; then
-  dev_list="${dev_list} libav-tools"
-fi
-
-# Some packages are only needed if the distribution actually supports
-# installing them.
-if package_exists appmenu-gtk; then
-  lib_list="$lib_list appmenu-gtk"
-fi
-if package_exists libgnome-keyring0; then
-  lib_list="${lib_list} libgnome-keyring0"
-fi
-if package_exists libgnome-keyring-dev; then
-  lib_list="${lib_list} libgnome-keyring-dev"
-fi
-if package_exists libvulkan-dev; then
-  dev_list="${dev_list} libvulkan-dev"
-fi
-if package_exists libvulkan1; then
-  lib_list="${lib_list} libvulkan1"
-fi
-if package_exists libinput10; then
-  lib_list="${lib_list} libinput10"
-fi
-if package_exists libinput-dev; then
-    dev_list="${dev_list} libinput-dev"
-fi
-if package_exists snapcraft; then
-    dev_list="${dev_list} snapcraft"
-fi
-
-# Cross-toolchain strip is needed for building the sysroots.
-if package_exists binutils-arm-linux-gnueabihf; then
-  dev_list="${dev_list} binutils-arm-linux-gnueabihf"
-fi
-if package_exists binutils-aarch64-linux-gnu; then
-  dev_list="${dev_list} binutils-aarch64-linux-gnu"
-fi
-if package_exists binutils-mipsel-linux-gnu; then
-  dev_list="${dev_list} binutils-mipsel-linux-gnu"
-fi
-if package_exists binutils-mips64el-linux-gnuabi64; then
-  dev_list="${dev_list} binutils-mips64el-linux-gnuabi64"
-fi
-
-# When cross building for arm/Android on 64-bit systems the host binaries
-# that are part of v8 need to be compiled with -m32 which means
-# that basic multilib support is needed.
-if file -L /sbin/init | grep -q 'ELF 64-bit'; then
-  # gcc-multilib conflicts with the arm cross compiler but
-  # g++-X.Y-multilib gives us the 32-bit support that we need. Find out the
-  # appropriate value of X and Y by seeing what version the current
-  # distribution's g++-multilib package depends on.
-  multilib_package=$(apt-cache depends g++-multilib --important | \
-      grep -E --color=never --only-matching '\bg\+\+-[0-9.]+-multilib\b')
-  lib32_list="$lib32_list $multilib_package"
-fi
-
-if [ "$do_inst_syms" = "1" ]; then
-  echo "Including debugging symbols."
-
-  # Debian is in the process of transitioning to automatic debug packages, which
-  # have the -dbgsym suffix (https://wiki.debian.org/AutomaticDebugPackages).
-  # Untransitioned packages have the -dbg suffix.  And on some systems, neither
-  # will be available, so exclude the ones that are missing.
-  dbg_package_name() {
-    if package_exists "$1-dbgsym"; then
-      echo "$1-dbgsym"
-    elif package_exists "$1-dbg"; then
-      echo "$1-dbg"
-    fi
-  }
-
-  for package in "${common_lib_list}"; do
-    dbg_list="$dbg_list $(dbg_package_name ${package})"
-  done
-
-  # Debugging symbols packages not following common naming scheme
-  if [ "$(dbg_package_name libstdc++6)" == "" ]; then
-    if package_exists libstdc++6-8-dbg; then
-      dbg_list="${dbg_list} libstdc++6-8-dbg"
-    elif package_exists libstdc++6-7-dbg; then
-      dbg_list="${dbg_list} libstdc++6-7-dbg"
-    elif package_exists libstdc++6-6-dbg; then
-      dbg_list="${dbg_list} libstdc++6-6-dbg"
-    elif package_exists libstdc++6-5-dbg; then
-      dbg_list="${dbg_list} libstdc++6-5-dbg"
-    elif package_exists libstdc++6-4.9-dbg; then
-      dbg_list="${dbg_list} libstdc++6-4.9-dbg"
-    elif package_exists libstdc++6-4.8-dbg; then
-      dbg_list="${dbg_list} libstdc++6-4.8-dbg"
-    elif package_exists libstdc++6-4.7-dbg; then
-      dbg_list="${dbg_list} libstdc++6-4.7-dbg"
-    elif package_exists libstdc++6-4.6-dbg; then
-      dbg_list="${dbg_list} libstdc++6-4.6-dbg"
-    fi
-  fi
-  if [ "$(dbg_package_name libatk1.0-0)" == "" ]; then
-    dbg_list="$dbg_list $(dbg_package_name libatk1.0)"
-  fi
-  if [ "$(dbg_package_name libpango-1.0-0)" == "" ]; then
-    dbg_list="$dbg_list $(dbg_package_name libpango1.0-dev)"
-  fi
-else
-  echo "Skipping debugging symbols."
-  dbg_list=
-fi
-
-if [ "$do_inst_lib32" = "1" ]; then
-  echo "Including 32-bit libraries."
-else
-  echo "Skipping 32-bit libraries."
-  lib32_list=
-fi
-
-if [ "$do_inst_android" = "1" ]; then
-  echo "Including Android dependencies."
-else
-  echo "Skipping Android dependencies."
-fi
-
-if [ "$do_inst_arm" = "1" ]; then
-  echo "Including ARM cross toolchain."
-else
-  echo "Skipping ARM cross toolchain."
-  arm_list=
-fi
-
-if [ "$do_inst_nacl" = "1" ]; then
-  echo "Including NaCl, NaCl toolchain, NaCl ports dependencies."
-else
-  echo "Skipping NaCl, NaCl toolchain, NaCl ports dependencies."
-  nacl_list=
-fi
-
-filtered_backwards_compatible_list=
-if [ "$do_inst_backwards_compatible" = "1" ]; then
-  echo "Including backwards compatible packages."
-  for package in ${backwards_compatible_list}; do
-    if package_exists ${package}; then
-      filtered_backwards_compatible_list+=" ${package}"
-    fi
-  done
-fi
-
-# The `sort -r -s -t: -k2` sorts all the :i386 packages to the front, to avoid
-# confusing dpkg-query (crbug.com/446172).
-packages="$(
-  echo "${dev_list} ${lib_list} ${dbg_list} ${lib32_list} ${arm_list}" \
-       "${nacl_list}" ${filtered_backwards_compatible_list} | tr " " "\n" | \
-       sort -u | sort -r -s -t: -k2 | tr "\n" " "
-)"
-
-if [ 1 -eq "${do_quick_check-0}" ] ; then
-  if ! missing_packages="$(dpkg-query -W -f ' ' ${packages} 2>&1)"; then
-    # Distinguish between packages that actually aren't available to the
-    # system (i.e. not in any repo) and packages that just aren't known to
-    # dpkg (i.e. managed by apt).
-    missing_packages="$(echo "${missing_packages}" | awk '{print $NF}')"
-    not_installed=""
-    unknown=""
-    for p in ${missing_packages}; do
-      if apt-cache show ${p} > /dev/null 2>&1; then
-        not_installed="${p}\n${not_installed}"
-      else
-        unknown="${p}\n${unknown}"
-      fi
-    done
-    if [ -n "${not_installed}" ]; then
-      echo "WARNING: The following packages are not installed:"
-      echo -e "${not_installed}" | sed -e "s/^/  /"
-    fi
-    if [ -n "${unknown}" ]; then
-      echo "WARNING: The following packages are unknown to your system"
-      echo "(maybe missing a repo or need to 'sudo apt-get update'):"
-      echo -e "${unknown}" | sed -e "s/^/  /"
-    fi
-    exit 1
-  fi
-  exit 0
-fi
-
-echo "Finding missing packages..."
-# Intentionally leaving $packages unquoted so it's more readable.
-echo "Packages required: " $packages
-echo
-query_cmd="apt-get --just-print install $(echo $packages)"
-if cmd_output="$(LANGUAGE=en LANG=C $query_cmd)"; then
-  new_list=$(echo "$cmd_output" |
-    sed -e '1,/The following NEW packages will be installed:/d;s/^  //;t;d' |
-    sed 's/ *$//')
-  upgrade_list=$(echo "$cmd_output" |
-    sed -e '1,/The following packages will be upgraded:/d;s/^  //;t;d' |
-    sed 's/ *$//')
-  if [ -z "$new_list" ] && [ -z "$upgrade_list" ]; then
-    echo "No missing packages, and the packages are up to date."
-  else
-    echo "Installing and upgrading packages: $new_list $upgrade_list."
-    sudo apt-get install ${do_quietly-} ${new_list} ${upgrade_list}
-  fi
-  echo
-else
-  # An apt-get exit status of 100 indicates that a real error has occurred.
-
-  # I am intentionally leaving out the '"'s around query_cmd,
-  # as this makes it easier to cut and paste the output
-  echo "The following command failed: " ${query_cmd}
-  echo
-  echo "It produced the following output:"
-  echo "$cmd_output"
-  echo
-  echo "You will have to install the above packages yourself."
-  echo
-  exit 100
-fi
-
-# Install the Chrome OS default fonts. This must go after running
-# apt-get, since install-chromeos-fonts depends on curl.
-if [ "$do_inst_chromeos_fonts" != "0" ]; then
-  echo
-  echo "Installing Chrome OS fonts."
-  dir=`echo $0 | sed -r -e 's/\/[^/]+$//'`
-  if ! sudo $dir/linux/install-chromeos-fonts.py; then
-    echo "ERROR: The installation of the Chrome OS default fonts failed."
-    if [ `stat -f -c %T $dir` == "nfs" ]; then
-      echo "The reason is that your repo is installed on a remote file system."
-    else
-      echo "This is expected if your repo is installed on a remote file system."
-    fi
-    echo "It is recommended to install your repo on a local file system."
-    echo "You can skip the installation of the Chrome OS default fonts with"
-    echo "the command line option: --no-chromeos-fonts."
-    exit 1
-  fi
-else
-  echo "Skipping installation of Chrome OS fonts."
-fi
-
-echo "Installing locales."
-CHROMIUM_LOCALES="da_DK.UTF-8 fr_FR.UTF-8 he_IL.UTF-8 zh_TW.UTF-8"
-LOCALE_GEN=/etc/locale.gen
-if [ -e ${LOCALE_GEN} ]; then
-  OLD_LOCALE_GEN="$(cat /etc/locale.gen)"
-  for CHROMIUM_LOCALE in ${CHROMIUM_LOCALES}; do
-    sudo sed -i "s/^# ${CHROMIUM_LOCALE}/${CHROMIUM_LOCALE}/" ${LOCALE_GEN}
-  done
-  # Regenerating locales can take a while, so only do it if we need to.
-  if (echo "${OLD_LOCALE_GEN}" | cmp -s ${LOCALE_GEN}); then
-    echo "Locales already up-to-date."
-  else
-    sudo locale-gen
-  fi
-else
-  for CHROMIUM_LOCALE in ${CHROMIUM_LOCALES}; do
-    sudo locale-gen ${CHROMIUM_LOCALE}
-  done
-fi
+exec "$(cd $(dirname $0) && pwd)/install-build-deps.py" "$@"
diff --git a/build/util/android_chrome_version.py b/build/util/android_chrome_version.py
index b716285e..b50847f4 100755
--- a/build/util/android_chrome_version.py
+++ b/build/util/android_chrome_version.py
@@ -104,7 +104,6 @@
         ('TRICHROME_64_32', 'TRICHROME', '64_32'),
         ('TRICHROME_64_32_HIGH', 'TRICHROME', '64_32_high'),
         ('TRICHROME_64', 'TRICHROME', '64'),
-        ('TRICHROME_64_HIGH', 'TRICHROME', '64_32_high'),  # Deprecated.
         ('TRICHROME_AUTO_64_32', 'TRICHROME_AUTO', '64_32'),
         ('TRICHROME_BETA', 'TRICHROME_BETA', '32_64'),
         ('TRICHROME_32_BETA', 'TRICHROME_BETA', '32'),
@@ -112,8 +111,6 @@
         ('TRICHROME_64_32_BETA', 'TRICHROME_BETA', '64_32'),
         ('TRICHROME_64_32_HIGH_BETA', 'TRICHROME_BETA', '64_32_high'),
         ('TRICHROME_64_BETA', 'TRICHROME_BETA', '64'),
-        # Deprecated
-        ('TRICHROME_64_HIGH_BETA', 'TRICHROME_BETA', '64_32_high'),
         ('WEBVIEW_STABLE', 'WEBVIEW_STABLE', '32_64'),
         ('WEBVIEW_BETA', 'WEBVIEW_BETA', '32_64'),
         ('WEBVIEW_DEV', 'WEBVIEW_DEV', '32_64'),
diff --git a/build/util/android_chrome_version_test.py b/build/util/android_chrome_version_test.py
index 61aae912..6213935 100644
--- a/build/util/android_chrome_version_test.py
+++ b/build/util/android_chrome_version_test.py
@@ -177,7 +177,7 @@
     arch_trichrome_32_64_version_code = output['TRICHROME_32_64_VERSION_CODE']
     arch_trichrome_64_32_version_code = output['TRICHROME_64_32_VERSION_CODE']
     arch_trichrome_64_32_high_version_code = output[
-        'TRICHROME_64_HIGH_VERSION_CODE']
+        'TRICHROME_64_32_HIGH_VERSION_CODE']
     arch_trichrome_64_version_code = output['TRICHROME_64_VERSION_CODE']
     arch_trichrome_auto_64_32_version_code = output[
         'TRICHROME_AUTO_64_32_VERSION_CODE']
@@ -501,7 +501,7 @@
     arch_trichrome_32_64_version_code = output['TRICHROME_32_64_VERSION_CODE']
     arch_trichrome_64_32_version_code = output['TRICHROME_64_32_VERSION_CODE']
     arch_trichrome_64_32_high_version_code = output[
-        'TRICHROME_64_HIGH_VERSION_CODE']
+        'TRICHROME_64_32_HIGH_VERSION_CODE']
     arch_trichrome_64_version_code = output['TRICHROME_64_VERSION_CODE']
     arch_trichrome_auto_64_32_version_code = output[
         'TRICHROME_AUTO_64_32_VERSION_CODE']
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 9f19e64..5b4f0d9 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -348,6 +348,7 @@
       "//chrome/browser/password_entry_edit:public_java",
       "//chrome/browser/password_manager/android:java",
       "//chrome/browser/password_manager/android:settings_interface_java",
+      "//chrome/browser/password_manager/android/pwd_migration:java",
       "//chrome/browser/policy/android:java",
       "//chrome/browser/preferences:java",
       "//chrome/browser/prefetch/android:java",
@@ -3376,7 +3377,6 @@
     "java/src/org/chromium/chrome/browser/query_tiles/QueryTileUtils.java",
     "java/src/org/chromium/chrome/browser/query_tiles/TileProviderFactory.java",
     "java/src/org/chromium/chrome/browser/query_tiles/TileServiceUtils.java",
-    "java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java",
     "java/src/org/chromium/chrome/browser/renderer_host/ChromeNavigationUIData.java",
     "java/src/org/chromium/chrome/browser/resources/ResourceMapper.java",
     "java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 931e70e2d..e941b414 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -35,7 +35,6 @@
   "java/src/org/chromium/chrome/browser/DevToolsServer.java",
   "java/src/org/chromium/chrome/browser/DragAndDropLauncherActivity.java",
   "java/src/org/chromium/chrome/browser/FileProviderHelper.java",
-  "java/src/org/chromium/chrome/browser/tasks/HomeSurfaceTracker.java",
   "java/src/org/chromium/chrome/browser/IntentHandler.java",
   "java/src/org/chromium/chrome/browser/KeyboardShortcuts.java",
   "java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java",
@@ -972,7 +971,6 @@
   "java/src/org/chromium/chrome/browser/quickactionsearchwidget/QuickActionSearchWidgetProvider.java",
   "java/src/org/chromium/chrome/browser/read_later/ReadLaterIPHController.java",
   "java/src/org/chromium/chrome/browser/read_later/ReadingListBackPressHandler.java",
-  "java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java",
   "java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java",
   "java/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationController.java",
   "java/src/org/chromium/chrome/browser/renderer_host/ChromeNavigationUIData.java",
@@ -1129,6 +1127,7 @@
   "java/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicy.java",
   "java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java",
   "java/src/org/chromium/chrome/browser/tasks/EngagementTimeUtil.java",
+  "java/src/org/chromium/chrome/browser/tasks/HomeSurfaceTracker.java",
   "java/src/org/chromium/chrome/browser/tasks/JourneyManager.java",
   "java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java",
   "java/src/org/chromium/chrome/browser/tasks/TasksUma.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivitySessionTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivitySessionTracker.java
index 1f07eeb..d7b005d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivitySessionTracker.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivitySessionTracker.java
@@ -36,7 +36,6 @@
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileManagerUtils;
-import org.chromium.chrome.browser.read_later.ReadingListBridge;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.translate.TranslateBridge;
 import org.chromium.components.browser_ui.accessibility.FontSizePrefs;
@@ -170,7 +169,6 @@
             mVariationsSession.start();
             mOmahaServiceStartDelayer.onForegroundSessionStart();
             AppHooks.get().getChimeDelegate().startSession();
-            ReadingListBridge.onStartChromeForeground();
             PasswordManagerLifecycleHelper.getInstance().onStartForegroundSession();
 
             // Track the ratio of Chrome startups that are caused by notification clicks.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java
index 9389ea83..1c8e3c1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImpl.java
@@ -5,24 +5,15 @@
 package org.chromium.chrome.browser.app.omnibox;
 
 import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.net.Uri;
 
 import androidx.annotation.NonNull;
 
 import org.chromium.base.IntentUtils;
 import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
-import org.chromium.chrome.browser.document.ChromeLauncherActivity;
-import org.chromium.chrome.browser.history_clusters.HistoryClustersCoordinator;
 import org.chromium.chrome.browser.omnibox.suggestions.ActionChipsDelegate;
 import org.chromium.chrome.browser.omnibox.suggestions.SuggestionsMetrics;
-import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
-import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
 import org.chromium.components.browser_ui.settings.SettingsLauncher.SettingsFragment;
@@ -36,23 +27,34 @@
 import org.chromium.content_public.browser.LoadUrlParams;
 
 import java.net.URISyntaxException;
+import java.util.function.Consumer;
 
 /**
  * Handle the events related to {@link OmniboxAction}.
+ * TODO(crbug/1418077): repurpose as a OmniboxActionFactoryImpl, move `execute()` to OmniboxAction
+ * instances.
  */
 public class ActionChipsDelegateImpl implements ActionChipsDelegate {
     private final @NonNull Context mContext;
     private final @NonNull SettingsLauncher mSettingsLauncher;
-    private final @NonNull Supplier<HistoryClustersCoordinator> mHistoryClustersCoordinatorSupplier;
+    private final @NonNull Consumer<String> mOpenUrlInExistingTabElseNewTabCb;
+    private final @NonNull Runnable mOpenIncognitoTabCb;
+    private final @NonNull Runnable mOpenPasswordSettingsCb;
+    private final @NonNull Consumer<String> mOpenHistoryClustersForQueryCb;
     private final @NonNull Supplier<Tab> mTabSupplier;
 
-    public ActionChipsDelegateImpl(@NonNull Context context,
-            @NonNull Supplier<HistoryClustersCoordinator> historyClustersCoordinatorSupplier,
-            @NonNull Supplier<Tab> tabSupplier) {
+    public ActionChipsDelegateImpl(@NonNull Context context, @NonNull Supplier<Tab> tabSupplier,
+            @NonNull SettingsLauncher settingsLauncher,
+            @NonNull Consumer<String> openUrlInExistingTabElseNewTabCb,
+            @NonNull Runnable openIncognitoTabCb, @NonNull Runnable openPasswordSettingsCb,
+            @NonNull Consumer<String> openHistoryClustersForQueryCb) {
         mContext = context;
-        mSettingsLauncher = new SettingsLauncherImpl();
-        mHistoryClustersCoordinatorSupplier = historyClustersCoordinatorSupplier;
         mTabSupplier = tabSupplier;
+        mSettingsLauncher = settingsLauncher;
+        mOpenUrlInExistingTabElseNewTabCb = openUrlInExistingTabElseNewTabCb;
+        mOpenIncognitoTabCb = openIncognitoTabCb;
+        mOpenPasswordSettingsCb = openPasswordSettingsCb;
+        mOpenHistoryClustersForQueryCb = openHistoryClustersForQueryCb;
     }
 
     private void executePedalAction(OmniboxPedal pedal) {
@@ -85,18 +87,11 @@
             case OmniboxPedalType.PLAY_CHROME_DINO_GAME:
                 loadPageInCurrentTab(UrlConstants.CHROME_DINO_URL);
                 break;
-
             case OmniboxPedalType.MANAGE_PASSWORDS:
-                PasswordManagerLauncher.showPasswordSettings(mContext,
-                        ManagePasswordsReferrer.CHROME_SETTINGS,
-                        // clang-format off: trying to be clever even with curly braces.
-                        () -> mTabSupplier.get().getWindowAndroid().getModalDialogManager(),
-                        // clang-format on
-                        /*managePasskeys=*/false);
+                mOpenPasswordSettingsCb.run();
                 break;
             case OmniboxPedalType.LAUNCH_INCOGNITO:
-                startActivity(IntentHandler.createTrustedOpenNewTabIntent(
-                        mContext.getApplicationContext(), /*incognito=*/true));
+                mOpenIncognitoTabCb.run();
                 break;
         }
         SuggestionsMetrics.recordPedalUsed(pedalId);
@@ -110,11 +105,7 @@
                 break;
 
             case OmniboxActionType.HISTORY_CLUSTERS:
-                var historyClustersCoordinator = mHistoryClustersCoordinatorSupplier.get();
-                if (historyClustersCoordinator != null) {
-                    historyClustersCoordinator.openHistoryClustersUi(
-                            HistoryClustersAction.from(action).query);
-                }
+                mOpenHistoryClustersForQueryCb.accept(HistoryClustersAction.from(action).query);
                 break;
 
             case OmniboxActionType.ACTION_IN_SUGGEST:
@@ -135,11 +126,7 @@
         if (tab.isUserInteractable()) {
             tab.loadUrl(new LoadUrlParams(url));
         } else {
-            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
-            intent.setComponent(new ComponentName(
-                    mContext.getApplicationContext(), ChromeLauncherActivity.class));
-            intent.putExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
-            startActivity(intent);
+            mOpenUrlInExistingTabElseNewTabCb.accept(url);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandler.java
index b9404c0..e6431112 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandler.java
@@ -18,12 +18,15 @@
     private static final int MAXIMUM_NUMBER_OF_SEARCH_RESULTS = 500;
 
     private final BookmarkModel mBookmarkModel;
+    private final BookmarkUiPrefs mBookmarkUiPrefs;
 
     /**
      * @param bookmarkModel The underlying source of bookmark data.
+     * @param bookmarkUiPrefs Stores display preferences for bookmarks.
      */
-    public BasicBookmarkQueryHandler(BookmarkModel bookmarkModel) {
+    public BasicBookmarkQueryHandler(BookmarkModel bookmarkModel, BookmarkUiPrefs bookmarkUiPrefs) {
         mBookmarkModel = bookmarkModel;
+        mBookmarkUiPrefs = bookmarkUiPrefs;
     }
 
     @Override
@@ -41,8 +44,8 @@
             }
 
             BookmarkItem bookmarkItem = mBookmarkModel.getBookmarkById(bookmarkId);
-            BookmarkListEntry bookmarkListEntry =
-                    BookmarkListEntry.createBookmarkEntry(bookmarkItem, powerBookmarkMeta);
+            BookmarkListEntry bookmarkListEntry = BookmarkListEntry.createBookmarkEntry(
+                    bookmarkItem, powerBookmarkMeta, mBookmarkUiPrefs.getBookmarkRowDisplayPref());
             bookmarkListEntries.add(bookmarkListEntry);
         }
 
@@ -61,8 +64,8 @@
         for (BookmarkId bookmarkId : searchIdList) {
             PowerBookmarkMeta powerBookmarkMeta = mBookmarkModel.getPowerBookmarkMeta(bookmarkId);
             BookmarkItem bookmarkItem = mBookmarkModel.getBookmarkById(bookmarkId);
-            BookmarkListEntry bookmarkListEntry =
-                    BookmarkListEntry.createBookmarkEntry(bookmarkItem, powerBookmarkMeta);
+            BookmarkListEntry bookmarkListEntry = BookmarkListEntry.createBookmarkEntry(
+                    bookmarkItem, powerBookmarkMeta, mBookmarkUiPrefs.getBookmarkRowDisplayPref());
             bookmarkListEntries.add(bookmarkListEntry);
         }
         return bookmarkListEntries;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
index 8a09126..2626dcb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
@@ -9,6 +9,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
+import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
 import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
 
@@ -28,7 +29,8 @@
     @IntDef({ViewType.INVALID, ViewType.PERSONALIZED_SIGNIN_PROMO, ViewType.PERSONALIZED_SYNC_PROMO,
             ViewType.SYNC_PROMO, ViewType.FOLDER, ViewType.BOOKMARK, ViewType.DIVIDER,
             ViewType.SECTION_HEADER, ViewType.SHOPPING_POWER_BOOKMARK, ViewType.TAG_CHIP_LIST,
-            ViewType.SHOPPING_FILTER, ViewType.IMPROVED_BOOKMARK})
+            ViewType.SHOPPING_FILTER, ViewType.IMPROVED_BOOKMARK_VISUAL,
+            ViewType.IMPROVED_BOOKMARK_COMPACT})
     public @interface ViewType {
         int INVALID = -1;
         int PERSONALIZED_SIGNIN_PROMO = 0;
@@ -41,7 +43,8 @@
         int SHOPPING_POWER_BOOKMARK = 7;
         int TAG_CHIP_LIST = 8;
         int SHOPPING_FILTER = 9;
-        int IMPROVED_BOOKMARK = 10;
+        int IMPROVED_BOOKMARK_VISUAL = 10;
+        int IMPROVED_BOOKMARK_COMPACT = 11;
     }
 
     /** Contains data used by section header in bookmark UI. */
@@ -73,13 +76,17 @@
     /**
      * Create an entry presenting a bookmark folder or bookmark.
      * @param bookmarkItem The data object created from the bookmark backend.
+     * @param meta The PowerBookmarkMeta for the bookmark.
+     * @param displayPref The display pref for the bookmark.
      */
-    static BookmarkListEntry createBookmarkEntry(
-            @Nonnull BookmarkItem bookmarkItem, @Nullable PowerBookmarkMeta meta) {
+    static BookmarkListEntry createBookmarkEntry(@Nonnull BookmarkItem bookmarkItem,
+            @Nullable PowerBookmarkMeta meta, @BookmarkRowDisplayPref int displayPref) {
         @ViewType
         int viewType = bookmarkItem.isFolder() ? ViewType.FOLDER : ViewType.BOOKMARK;
         if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
-            viewType = ViewType.IMPROVED_BOOKMARK;
+            viewType = displayPref == BookmarkRowDisplayPref.VISUAL
+                    ? ViewType.IMPROVED_BOOKMARK_VISUAL
+                    : ViewType.IMPROVED_BOOKMARK_COMPACT;
         } else if (meta != null && meta.hasShoppingSpecifics()) {
             viewType = ViewType.SHOPPING_POWER_BOOKMARK;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
index 99ce811c..8e45466 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
@@ -25,7 +25,6 @@
 import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
-import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
 import org.chromium.chrome.browser.commerce.ShoppingFeatures;
 import org.chromium.chrome.browser.commerce.ShoppingServiceFactory;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -45,10 +44,6 @@
 import org.chromium.components.image_fetcher.ImageFetcherFactory;
 import org.chromium.ui.KeyboardVisibilityDelegate;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
-import org.chromium.ui.modelutil.PropertyKey;
-import org.chromium.ui.modelutil.PropertyModel;
-import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
-import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder;
 
 /** Responsible for setting up sub-components and routing incoming/outgoing signals */
 public class BookmarkManagerCoordinator
@@ -184,8 +179,10 @@
         dragReorderableRecyclerViewAdapter.registerType(ViewType.SHOPPING_FILTER,
                 BookmarkManagerCoordinator::buildShoppingFilterView,
                 BookmarkManagerViewBinder::bindShoppingFilterView);
-        dragReorderableRecyclerViewAdapter.registerType(ViewType.IMPROVED_BOOKMARK,
-                this::buildAndInitImprovedBookmarkRow, ImprovedBookmarkRowViewBinder::bind);
+        dragReorderableRecyclerViewAdapter.registerType(ViewType.IMPROVED_BOOKMARK_VISUAL,
+                this::buildAndInitVisualImprovedBookmarkRow, ImprovedBookmarkRowViewBinder::bind);
+        dragReorderableRecyclerViewAdapter.registerType(ViewType.IMPROVED_BOOKMARK_COMPACT,
+                this::buildAndInitCompactImprovedBookmarkRow, ImprovedBookmarkRowViewBinder::bind);
 
         RecordUserAction.record("MobileBookmarkManagerOpen");
         if (!isDialogUi) {
@@ -288,43 +285,6 @@
                 FAVICON_MAX_CACHE_SIZE_BYTES);
     }
 
-    public void bindView(View view, @ViewType int viewType, PropertyModel model) {
-        ViewBinder<PropertyModel, View, PropertyKey> viewBinder = null;
-        switch (viewType) {
-            case ViewType.PERSONALIZED_SIGNIN_PROMO:
-            case ViewType.PERSONALIZED_SYNC_PROMO:
-                viewBinder = BookmarkManagerViewBinder::bindPersonalizedPromoView;
-                break;
-            case ViewType.SYNC_PROMO:
-                viewBinder = BookmarkManagerViewBinder::bindLegacyPromoView;
-                break;
-            case ViewType.SECTION_HEADER:
-                viewBinder = BookmarkManagerViewBinder::bindSectionHeaderView;
-                break;
-            case ViewType.FOLDER:
-                viewBinder = BookmarkManagerViewBinder::bindBookmarkFolderView;
-                break;
-            case ViewType.BOOKMARK:
-                viewBinder = BookmarkManagerViewBinder::bindBookmarkItemView;
-                break;
-            case ViewType.SHOPPING_POWER_BOOKMARK:
-                viewBinder = BookmarkManagerViewBinder::bindShoppingItemView;
-                break;
-            case ViewType.DIVIDER:
-                viewBinder = BookmarkManagerViewBinder::bindDividerView;
-                break;
-            case ViewType.SHOPPING_FILTER:
-                viewBinder = BookmarkManagerViewBinder::bindShoppingFilterView;
-                break;
-            case ViewType.IMPROVED_BOOKMARK:
-                viewBinder = ImprovedBookmarkRowViewBinder::bind;
-                break;
-            default:
-                assert false;
-        }
-        PropertyModelChangeProcessor.create(model, view, viewBinder);
-    }
-
     @VisibleForTesting
     View buildPersonalizedPromoView(ViewGroup parent) {
         return mPromoHeaderManager.createPersonalizedSigninAndSyncPromoHolder(parent);
@@ -366,9 +326,14 @@
         return inflate(parent, org.chromium.chrome.R.layout.shopping_filter_row);
     }
 
-    ImprovedBookmarkRow buildAndInitImprovedBookmarkRow(ViewGroup parent) {
-        ImprovedBookmarkRow row = ImprovedBookmarkRow.buildView(parent.getContext(),
-                mBookmarkUiPrefs.getBookmarkRowDisplayPref() == BookmarkRowDisplayPref.VISUAL);
+    ImprovedBookmarkRow buildAndInitCompactImprovedBookmarkRow(ViewGroup parent) {
+        ImprovedBookmarkRow row = ImprovedBookmarkRow.buildView(parent.getContext(), false);
+        row.setSelectionDelegate(mSelectionDelegate);
+        return row;
+    }
+
+    ImprovedBookmarkRow buildAndInitVisualImprovedBookmarkRow(ViewGroup parent) {
+        ImprovedBookmarkRow row = ImprovedBookmarkRow.buildView(parent.getContext(), true);
         row.setSelectionDelegate(mSelectionDelegate);
         return row;
     }
@@ -407,6 +372,7 @@
     }
 
     // Testing methods.
+
     public BookmarkToolbarCoordinator getToolbarCoordinatorForTesting() {
         return mBookmarkToolbarCoordinator;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
index ad4a48a..6467380 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
@@ -26,6 +26,7 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
 import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location;
 import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
+import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.Observer;
 import org.chromium.chrome.browser.bookmarks.BookmarkUiState.BookmarkUiMode;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
@@ -61,9 +62,8 @@
 
 /** Responsible for BookmarkManager business logic. */
 // TODO(crbug.com/1416611): Remove BookmarkDelegate if possible.
-class BookmarkManagerMediator implements BookmarkDelegate, TestingDelegate,
-                                         PartnerBookmarksReader.FaviconUpdateObserver,
-                                         BookmarkUiPrefs.Observer {
+class BookmarkManagerMediator
+        implements BookmarkDelegate, TestingDelegate, PartnerBookmarksReader.FaviconUpdateObserver {
     private static final String EMPTY_QUERY = null;
 
     private static boolean sPreventLoadingForTesting;
@@ -303,6 +303,21 @@
         }
     };
 
+    private final BookmarkUiPrefs.Observer mBookmarkUiPrefsObserver = new Observer() {
+        @Override
+        @SuppressWarnings("NotifyDataSetChanged")
+        public void onBookmarkRowDisplayPrefChanged(@BookmarkRowDisplayPref int displayPref) {
+            mModelList.clear();
+            mDragReorderableRecyclerViewAdapter.notifyDataSetChanged();
+            if (getCurrentUiMode() == BookmarkUiMode.SEARCHING) {
+                search(mSearchText);
+            } else {
+                setBookmarks(
+                        mBookmarkQueryHandler.buildBookmarkListForParent(getCurrentFolderId()));
+            }
+        }
+    };
+
     private final ObserverList<BookmarkUiObserver> mUiObservers = new ObserverList<>();
     private final BookmarkDragStateDelegate mDragStateDelegate = new BookmarkDragStateDelegate();
     private final Context mContext;
@@ -377,14 +392,15 @@
         mPromoHeaderManager = new BookmarkPromoHeader(mContext, mProfile, this::updateHeader);
         mBookmarkUndoController = bookmarkUndoController;
         if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()) {
-            mBookmarkQueryHandler = new ImprovedBookmarkQueryHandler(mBookmarkModel);
+            mBookmarkQueryHandler =
+                    new ImprovedBookmarkQueryHandler(mBookmarkModel, bookmarkUiPrefs);
         } else {
-            mBookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
+            mBookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel, bookmarkUiPrefs);
         }
 
         mModelList = modelList;
         mBookmarkUiPrefs = bookmarkUiPrefs;
-        mBookmarkUiPrefs.addObserver(this);
+        mBookmarkUiPrefs.addObserver(mBookmarkUiPrefsObserver);
         mHideKeyboardRunnable = hideKeyboardRunnable;
 
         final @BookmarkRowDisplayPref int displayPref =
@@ -430,7 +446,7 @@
         mDragStateDelegate.destroy();
         mBookmarkQueryHandler.destroy();
 
-        mBookmarkUiPrefs.removeObserver(this);
+        mBookmarkUiPrefs.removeObserver(mBookmarkUiPrefsObserver);
 
         for (BookmarkUiObserver observer : mUiObservers) {
             observer.onDestroy();
@@ -838,12 +854,8 @@
         // back, but instead it sees items being changed.
         // TODO(https://crbug.com/1413463): Rework promo/header methods to simplify initial index.
         int index = hasPromoHeader() ? 1 : 0;
-
         for (BookmarkListEntry bookmarkListEntry : bookmarkListEntryList) {
-            updateOrAdd(index,
-                    BookmarkFeatures.isAndroidImprovedBookmarksEnabled()
-                            ? buildImprovedBookmarkRow(bookmarkListEntry, index)
-                            : buildBookmarkListItem(bookmarkListEntry));
+            updateOrAdd(index, buildBookmarkListItem(bookmarkListEntry, index));
             index++;
         }
 
@@ -1019,7 +1031,11 @@
         return new ListItem(bookmarkListEntry.getViewType(), propertyModel);
     }
 
-    private ListItem buildBookmarkListItem(BookmarkListEntry bookmarkListEntry) {
+    private ListItem buildBookmarkListItem(BookmarkListEntry bookmarkListEntry, int index) {
+        if (bookmarkListEntry.getViewType() == ViewType.IMPROVED_BOOKMARK_COMPACT
+                || bookmarkListEntry.getViewType() == ViewType.IMPROVED_BOOKMARK_VISUAL) {
+            return buildImprovedBookmarkRow(bookmarkListEntry, index);
+        }
         BookmarkItem bookmarkItem = bookmarkListEntry.getBookmarkItem();
         BookmarkId bookmarkId = bookmarkItem == null ? null : bookmarkItem.getId();
         PropertyModel propertyModel = new PropertyModel(BookmarkManagerProperties.ALL_KEYS);
@@ -1075,17 +1091,7 @@
             propertyModel.set(ImprovedBookmarkRowProperties.ACCESSORY_VIEW, null);
         }
 
-        return new ListItem(ViewType.IMPROVED_BOOKMARK, propertyModel);
-    }
-
-    // BookmarkUiPrefs.Observer implementation.
-
-    @Override
-    @SuppressWarnings("NotifyDataSetChanged")
-    public void onBookmarkRowDisplayPrefChanged() {
-        mRecyclerView.setAdapter(null);
-        mRecyclerView.setAdapter(mDragReorderableRecyclerViewAdapter);
-        mDragReorderableRecyclerViewAdapter.notifyDataSetChanged();
+        return new ListItem(bookmarkListEntry.getViewType(), propertyModel);
     }
 
     // ImprovedBookmarkRow methods.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefs.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefs.java
index b5a7dfc0..9d79bf9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefs.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefs.java
@@ -17,7 +17,7 @@
  * Self-documenting preference class for bookmarks.
  */
 public class BookmarkUiPrefs {
-    private static final @BookmarkRowDisplayPref int sInitialBookmarkRowDisplayPref =
+    private static final @BookmarkRowDisplayPref int INITIAL_BOOKMARK_ROW_DISPLAY_PREF =
             BookmarkRowDisplayPref.COMPACT;
 
     // This is persisted to preferences, entries shouldn't be reordered or removed.
@@ -30,15 +30,15 @@
 
     /** Observer for changes to prefs. */
     public interface Observer {
-        /** Called when the BookmarkRowDisplayPref changes. */
-        void onBookmarkRowDisplayPrefChanged();
+        /** Called when the current {@link BookmarkRowDisplayPref} changes. */
+        void onBookmarkRowDisplayPrefChanged(@BookmarkRowDisplayPref int displayPref);
     }
 
     private final SharedPreferencesManager mPrefsManager;
     private final ObserverList<Observer> mObservers = new ObserverList<>();
 
     /**
-     * @param prefsManager Instance of SharedPreferencesManager to read/write from prefs.
+     * @param prefsManager Instance of {@link SharedPreferencesManager} to read/write from prefs.
      */
     public BookmarkUiPrefs(SharedPreferencesManager prefsManager) {
         mPrefsManager = prefsManager;
@@ -62,25 +62,22 @@
             return getDisplayPrefForLegacy();
         }
 
-        if (mPrefsManager.contains(ChromePreferenceKeys.BOOKMARK_VISUALS_PREF)) {
-            return mPrefsManager.readInt(ChromePreferenceKeys.BOOKMARK_VISUALS_PREF);
-        } else {
-            return sInitialBookmarkRowDisplayPref;
-        }
+        return mPrefsManager.readInt(
+                ChromePreferenceKeys.BOOKMARKS_VISUALS_PREF, INITIAL_BOOKMARK_ROW_DISPLAY_PREF);
     }
 
     /**
      * Sets the value for the bookmark row display pref.
-     * @param pref The pref value to be set.
+     * @param displayPref The pref value to be set.
      */
-    public void setBookmarkRowDisplayPref(@BookmarkRowDisplayPref int pref) {
-        mPrefsManager.writeInt(ChromePreferenceKeys.BOOKMARK_VISUALS_PREF, pref);
-        for (Observer obs : mObservers) obs.onBookmarkRowDisplayPrefChanged();
+    public void setBookmarkRowDisplayPref(@BookmarkRowDisplayPref int displayPref) {
+        mPrefsManager.writeInt(ChromePreferenceKeys.BOOKMARKS_VISUALS_PREF, displayPref);
+        for (Observer obs : mObservers) obs.onBookmarkRowDisplayPrefChanged(displayPref);
     }
 
     /**
-     * Some places use @BookmarkRowDisplayPref even for legacy handling. This converts to the new
-     * display pref from feature flags.
+     * Some places use {@link BookmarkRowDisplayPref} even for legacy handling. This converts to the
+     * new display pref from feature flags.
      */
     public static @BookmarkRowDisplayPref int getDisplayPrefForLegacy() {
         assert !BookmarkFeatures.isAndroidImprovedBookmarksEnabled();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandler.java
index 3efcc816..9c82cd24 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandler.java
@@ -28,14 +28,18 @@
 
     private final BookmarkModel mBookmarkModel;
     private final BasicBookmarkQueryHandler mBasicBookmarkQueryHandler;
+    private final BookmarkUiPrefs mBookmarkUiPrefs;
 
     /**
      * Constructs a handle that operates on the given backend.
      * @param bookmarkModel The backend that holds the truth of what the bookmark state looks like.
+     * @param bookmarkUiPrefs Stores the display prefs for bookmarmks.
      */
-    public ImprovedBookmarkQueryHandler(BookmarkModel bookmarkModel) {
+    public ImprovedBookmarkQueryHandler(
+            BookmarkModel bookmarkModel, BookmarkUiPrefs bookmarkUiPrefs) {
         mBookmarkModel = bookmarkModel;
-        mBasicBookmarkQueryHandler = new BasicBookmarkQueryHandler(bookmarkModel);
+        mBookmarkUiPrefs = bookmarkUiPrefs;
+        mBasicBookmarkQueryHandler = new BasicBookmarkQueryHandler(bookmarkModel, mBookmarkUiPrefs);
     }
 
     @Override
@@ -76,7 +80,8 @@
         BookmarkItem bookmarkItem = mBookmarkModel.getBookmarkById(bookmarkId);
         // Root view items are never re-orderable, as it's not a single folder.
         bookmarkItem = new NoDragWrappedBookmarkItem(bookmarkItem);
-        return BookmarkListEntry.createBookmarkEntry(bookmarkItem, powerBookmarkMeta);
+        return BookmarkListEntry.createBookmarkEntry(
+                bookmarkItem, powerBookmarkMeta, mBookmarkUiPrefs.getBookmarkRowDisplayPref());
     }
 
     private int compareBookmarkListEntry(BookmarkListEntry entry1, BookmarkListEntry entry2) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
index 695c2ab6..e8051c9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
@@ -105,6 +105,7 @@
     void setAccessoryView(@Nullable View view) {
         mAccessoryViewGroup.removeAllViews();
         if (view == null) return;
+
         mAccessoryViewGroup.addView(view);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandler.java
index 1641124..10ebcd4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandler.java
@@ -21,16 +21,20 @@
     private final SyncService mSyncService;
     private final SyncStateChangedListener mSyncStateChangedListener = this::syncStateChanged;
     private final List<BookmarkId> mTopLevelFolders = new ArrayList<>();
+    private final BookmarkUiPrefs mBookmarkUiPrefs;
 
     /**
      * @param bookmarkModel The underlying source of bookmark data.
+     * @param bookmarkUiPrefs Stores display preferences for bookmarks.
      */
-    public LegacyBookmarkQueryHandler(BookmarkModel bookmarkModel) {
+    public LegacyBookmarkQueryHandler(
+            BookmarkModel bookmarkModel, BookmarkUiPrefs bookmarkUiPrefs) {
         mBookmarkModel = bookmarkModel;
         mBookmarkModel.finishLoadingBookmarkModel(this::onBookmarkModelLoaded);
         mSyncService = SyncService.get();
         mSyncService.addSyncStateChangedListener(mSyncStateChangedListener);
-        mBasicBookmarkQueryHandler = new BasicBookmarkQueryHandler(bookmarkModel);
+        mBasicBookmarkQueryHandler = new BasicBookmarkQueryHandler(bookmarkModel, bookmarkUiPrefs);
+        mBookmarkUiPrefs = bookmarkUiPrefs;
     }
 
     @Override
@@ -58,8 +62,8 @@
         for (BookmarkId bookmarkId : mTopLevelFolders) {
             PowerBookmarkMeta powerBookmarkMeta = mBookmarkModel.getPowerBookmarkMeta(bookmarkId);
             BookmarkItem bookmarkItem = mBookmarkModel.getBookmarkById(bookmarkId);
-            BookmarkListEntry bookmarkListEntry =
-                    BookmarkListEntry.createBookmarkEntry(bookmarkItem, powerBookmarkMeta);
+            BookmarkListEntry bookmarkListEntry = BookmarkListEntry.createBookmarkEntry(
+                    bookmarkItem, powerBookmarkMeta, mBookmarkUiPrefs.getBookmarkRowDisplayPref());
             bookmarkListEntries.add(bookmarkListEntry);
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java
deleted file mode 100644
index dfcd6b6b8..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBridge.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2020 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.read_later;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.R;
-
-/**
- * Contains JNI methods to needed by read later feature.
- */
-public final class ReadingListBridge {
-    private ReadingListBridge() {}
-
-    /**
-     * Called when Chrome starts in foreground.
-     */
-    public static void onStartChromeForeground() {
-        ReadingListBridgeJni.get().onStartChromeForeground();
-    }
-
-    @CalledByNative
-    private static String getNotificationTitle() {
-        return ContextUtils.getApplicationContext().getResources().getString(
-                R.string.reading_list_reminder_notification_title);
-    }
-
-    @CalledByNative
-    private static String getNotificationText(int unreadSize) {
-        return ContextUtils.getApplicationContext().getResources().getQuantityString(
-                R.plurals.reading_list_reminder_notification_subtitle, unreadSize, unreadSize);
-    }
-
-    @CalledByNative
-    private static void openReadingListPage() {
-        ReadingListUtils.showReadingList(/*isIncognito=*/false);
-    }
-
-    @NativeMethods
-    interface Natives {
-        void onStartChromeForeground();
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
index a94c4156..a814909 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
@@ -6,6 +6,7 @@
 
 import android.app.Activity;
 import android.app.SearchManager;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
@@ -27,7 +28,6 @@
 import org.chromium.base.Log;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.supplier.ObservableSupplierImpl;
-import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.supplier.UnownedUserDataSupplier;
 import org.chromium.blink.mojom.DisplayMode;
 import org.chromium.chrome.R;
@@ -36,6 +36,7 @@
 import org.chromium.chrome.browser.app.omnibox.ActionChipsDelegateImpl;
 import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton;
 import org.chromium.chrome.browser.back_press.BackPressManager;
+import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
 import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.crash.ChromePureJavaExceptionReporter;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
@@ -52,8 +53,11 @@
 import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsDropdownScrollListener;
 import org.chromium.chrome.browser.omnibox.suggestions.base.HistoryClustersProcessor.OpenHistoryClustersDelegate;
 import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler;
+import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
+import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
 import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManagerImpl;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabBuilder;
 import org.chromium.chrome.browser.tab.TabDelegateFactory;
@@ -246,8 +250,28 @@
             TabWindowManagerSingleton::getInstance, /*bookmarkState=*/(url) -> false,
             VoiceToolbarButtonController::isToolbarMicEnabled,
             /*merchantTrustSignalsCoordinatorSupplier=*/null,
-            new ActionChipsDelegateImpl(this, new OneshotSupplierImpl<>(),
-                () -> mSearchBoxDataProvider.getTab()), null,
+            new ActionChipsDelegateImpl(this,
+                () -> mSearchBoxDataProvider.getTab(),
+                new SettingsLauncherImpl(),
+                // TODO(ender): phase out callbacks when the modules below are components.
+                // Open URL in an existing, else new regular tab.
+                url -> {
+                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+                    intent.setComponent(new ComponentName(getApplicationContext(),
+                                        ChromeLauncherActivity.class));
+                    intent.putExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
+                    startActivity(intent);
+                },
+                // Open Incognito Tab callback:
+                () -> startActivity(IntentHandler.createTrustedOpenNewTabIntent(this, true)),
+                // Open Password Settings callback:
+                () ->
+                    PasswordManagerLauncher.showPasswordSettings(this,
+                            ManagePasswordsReferrer.CHROME_SETTINGS,
+                            () -> getModalDialogManager(), /*managePasskeys=*/false),
+                // Open History Clusters UI for Query:
+                query -> {}
+                ), null,
             ChromePureJavaExceptionReporter::reportJavaException, backPressManager,
             /*OmniboxSuggestionsDropdownScrollListener=*/this,
             new OpenHistoryClustersDelegate() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
index 31bcdfa3..c626877 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -5,8 +5,10 @@
 package org.chromium.chrome.browser.ui;
 
 import android.app.Fragment;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.CancellationSignal;
@@ -45,6 +47,7 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.bookmarks.TabBookmarker;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
+import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
 import org.chromium.chrome.browser.commerce.ShoppingServiceFactory;
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
@@ -55,6 +58,7 @@
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager;
 import org.chromium.chrome.browser.crash.ChromePureJavaExceptionReporter;
 import org.chromium.chrome.browser.directactions.DirectActionInitializer;
+import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.dom_distiller.ReaderModeToolbarButtonController;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.findinpage.FindToolbarManager;
@@ -93,6 +97,8 @@
 import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler;
 import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler.VoiceInteractionSource;
 import org.chromium.chrome.browser.paint_preview.DemoPaintPreview;
+import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
+import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingButtonController;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -301,8 +307,6 @@
     private final ActionChipsDelegate mActionChipsDelegate;
     private final boolean mInitializeUiWithIncognitoColors;
     private HistoryClustersCoordinator mHistoryClustersCoordinator;
-    private final OneshotSupplierImpl<HistoryClustersCoordinator>
-            mHistoryClustersCoordinatorSupplier = new OneshotSupplierImpl<>();
     private final Supplier<EphemeralTabCoordinator> mEphemeralTabCoordinatorSupplier;
     @Nullable
     private final BackPressManager mBackPressManager;
@@ -427,8 +431,32 @@
         mMenuOrKeyboardActionController.registerMenuOrKeyboardActionHandler(this);
         mActivityTabProvider = tabProvider;
 
-        mActionChipsDelegate = new ActionChipsDelegateImpl(
-                mActivity, mHistoryClustersCoordinatorSupplier, mActivityTabProvider);
+        mActionChipsDelegate = new ActionChipsDelegateImpl(mActivity, mActivityTabProvider,
+                new SettingsLauncherImpl(),
+                // TODO(ender): phase out callbacks when the modules below are components.
+                // Open URL in an existing, else new regular tab.
+                url
+                -> {
+                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+                    intent.setComponent(new ComponentName(mActivity, ChromeLauncherActivity.class));
+                    intent.putExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
+                    mActivity.startActivity(intent);
+                },
+                // Open Incognito Tab callback:
+                ()
+                        -> mActivity.startActivity(
+                                IntentHandler.createTrustedOpenNewTabIntent(mActivity, true)),
+                // Open Password Settings callback:
+                ()
+                        -> PasswordManagerLauncher.showPasswordSettings(mActivity,
+                                ManagePasswordsReferrer.CHROME_SETTINGS,
+                                mModalDialogManagerSupplier, /*managePasskeys=*/false),
+                // Open History Clusters UI for Query:
+                query -> {
+                    if (mHistoryClustersCoordinator != null) {
+                        mHistoryClustersCoordinator.openHistoryClustersUi(query);
+                    }
+                });
 
         // This little bit of arithmetic is necessary because of Java doesn't like accepting
         // Supplier<BaseImpl> where Supplier<Base> is expected. We should remove the need for
@@ -870,7 +898,6 @@
             mHistoryClustersCoordinator = new HistoryClustersCoordinator(profile, mActivity,
                     TemplateUrlServiceFactory.getForProfile(profile), historyClustersDelegate,
                     ChromeAccessibilityUtil.get(), mSnackbarManagerSupplier.get());
-            mHistoryClustersCoordinatorSupplier.set(mHistoryClustersCoordinator);
         }
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
index 21adcede3..f8fde31 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
@@ -23,11 +23,11 @@
 import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
 
 import android.text.TextUtils;
-import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import androidx.annotation.IdRes;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
@@ -427,12 +427,10 @@
         assertEquals("Wrong number of items after searching for non-existent item.", 0,
                 mAdapter.getItemCount());
 
-        runOnUiThreadBlocking(
-                () -> mBookmarkManagerCoordinator.getToolbarForTesting().hideSearchView());
+        runOnUiThreadBlocking(() -> mToolbar.hideSearchView());
         assertEquals("Wrong number of items after closing search UI.", 3, mAdapter.getItemCount());
         assertEquals(BookmarkUiMode.FOLDER, mDelegate.getCurrentUiMode());
-        assertEquals(
-                TEST_FOLDER_TITLE, mBookmarkManagerCoordinator.getToolbarForTesting().getTitle());
+        assertEquals(TEST_FOLDER_TITLE, mToolbar.getTitle());
     }
 
     @Test
@@ -522,9 +520,7 @@
         openFolder(testFolder);
 
         View search_view = mToolbar.findViewById(R.id.search_view);
-
-        runOnUiThreadBlocking(
-                () -> mToolbar.onMenuItemClick(mToolbar.getMenu().findItem(R.id.search_menu_id)));
+        clickToolbarMenuItem(R.id.search_menu_id);
 
         // Despite being in search mode, this is the initial query state, and the previous 1
         // bookmark inside of testFolder should be shown.
@@ -540,10 +536,7 @@
         // that operate on the selected rows.
         assertNotEquals(search_view.getVisibility(), View.VISIBLE);
 
-        runOnUiThreadBlocking(() -> {
-            mToolbar.onMenuItemClick(
-                    mToolbar.getMenu().findItem(R.id.selection_mode_delete_menu_id));
-        });
+        clickToolbarMenuItem(R.id.selection_mode_delete_menu_id);
 
         // Should now be kicked back into an empty search string query, not the initial query. This
         // is why 3 items should now be visible, the two folders and the other url bookmark.
@@ -580,12 +573,7 @@
         // right now is the empty string. This will return all bookmarks (3).
         toggleSelectionAndEndAnimation(testFolder2,
                 (BookmarkRow) mItemsContainer.findViewHolderForLayoutPosition(2).itemView);
-        runOnUiThreadBlocking(
-                ()
-                        -> mBookmarkManagerCoordinator.getToolbarForTesting().onMenuItemClick(
-                                mBookmarkManagerCoordinator.getToolbarForTesting()
-                                        .getMenu()
-                                        .findItem(R.id.selection_mode_delete_menu_id)));
+        clickToolbarMenuItem(R.id.selection_mode_delete_menu_id);
 
         // Should still be searching with the folder gone.
         assertEquals("Wrong number of items.", 3, mAdapter.getItemCount());
@@ -683,8 +671,7 @@
 
         openBookmarkManager();
 
-        runOnUiThreadBlocking(
-                () -> mToolbar.onMenuItemClick(mToolbar.getMenu().findItem(R.id.close_menu_id)));
+        clickToolbarMenuItem(R.id.close_menu_id);
 
         ApplicationTestUtils.waitForActivityState(mBookmarkActivity, Stage.DESTROYED);
 
@@ -731,8 +718,7 @@
         CriteriaHelper.pollUiThread(test::isChecked, "Expected item \"test\" to become selected");
 
         assertEquals("Expected bookmark toolbar to be selection mode",
-                mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(),
-                ViewType.SELECTION_VIEW);
+                mToolbar.getCurrentViewType(), ViewType.SELECTION_VIEW);
         assertEquals("Expected more button of selected item to be gone when drag is active.",
                 View.GONE, testMoreButton.getVisibility());
         assertEquals("Expected drag handle of selected item to be visible when drag is active.",
@@ -759,8 +745,6 @@
         openBookmarkManager();
         BookmarkTestUtil.openMobileBookmarks(mItemsContainer, mDelegate, mBookmarkModel);
 
-        MenuItem searchMenuItem = mToolbar.getMenu().findItem(R.id.search_menu_id);
-
         BookmarkRow test =
                 (BookmarkRow) mItemsContainer.findViewHolderForAdapterPosition(2).itemView;
         View testMoreButton = test.findViewById(R.id.more);
@@ -770,13 +754,10 @@
         View aMoreButton = a.findViewById(R.id.more);
         View aDragHandle = a.getDragHandleViewForTesting();
 
-        runOnUiThreadBlocking(() -> mToolbar.onMenuItemClick(searchMenuItem));
+        clickToolbarMenuItem(R.id.search_menu_id);
 
         // Callback occurs when Item "test" is selected.
-        CriteriaHelper.pollUiThread(
-                ()
-                        -> mBookmarkManagerCoordinator.getToolbarForTesting().isSearching(),
-                "Expected to enter search mode");
+        CriteriaHelper.pollUiThread(() -> mToolbar.isSearching(), "Expected to enter search mode");
 
         toggleSelectionAndEndAnimation(testId, test);
 
@@ -1194,14 +1175,10 @@
         addFolder(TEST_FOLDER_TITLE);
         openBookmarkManager();
 
-        MenuItem searchMenuItem = mToolbar.getMenu().findItem(R.id.search_menu_id);
-        runOnUiThreadBlocking(() -> mToolbar.onMenuItemClick(searchMenuItem));
+        clickToolbarMenuItem(R.id.search_menu_id);
 
         // Callback occurs when Item "test" is selected.
-        CriteriaHelper.pollUiThread(
-                ()
-                        -> mBookmarkManagerCoordinator.getToolbarForTesting().isSearching(),
-                "Expected to enter search mode");
+        CriteriaHelper.pollUiThread(() -> mToolbar.isSearching(), "Expected to enter search mode");
 
         View testFolder = mItemsContainer.findViewHolderForAdapterPosition(0).itemView;
         assertEquals("Wrong bookmark item selected.", TEST_FOLDER_TITLE,
@@ -1492,8 +1469,7 @@
             assertFalse("Item is not deleted", isItemPresentInBookmarkList(TEST_PAGE_TITLE_GOOGLE));
             assertEquals(2, mAdapter.getItemCount());
             assertEquals("Bookmark View should be back to normal view",
-                    mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(),
-                    ViewType.NORMAL_VIEW);
+                    mToolbar.getCurrentViewType(), ViewType.NORMAL_VIEW);
         });
     }
 
@@ -1534,8 +1510,7 @@
             assertEquals(2, mAdapter.getItemCount());
             assertTrue("Item selected should not be cleared", aRow.isItemSelected());
             assertEquals("Should stay in selection mode because there is one selected",
-                    mBookmarkManagerCoordinator.getToolbarForTesting().getCurrentViewType(),
-                    ViewType.SELECTION_VIEW);
+                    mToolbar.getCurrentViewType(), ViewType.SELECTION_VIEW);
         });
     }
 
@@ -1865,12 +1840,9 @@
     }
 
     private void enterSearch() throws Exception {
-        MenuItem searchMenuItem = mToolbar.getMenu().findItem(R.id.search_menu_id);
-        runOnUiThreadBlocking(() -> mToolbar.onMenuItemClick(searchMenuItem));
+        clickToolbarMenuItem(R.id.search_menu_id);
         CriteriaHelper.pollUiThread(
-                ()
-                        -> mBookmarkManagerCoordinator.getToolbarForTesting().isSearching(),
-                "Expected to enter search mode");
+                () -> { return mToolbar.isSearching(); }, "Expected to enter search mode");
     }
 
     private void clickMoreButtonOnFirstItem(String expectedBookmarkItemTitle) throws Exception {
@@ -1913,7 +1885,7 @@
         runOnUiThreadBlocking(() -> {
             mDelegate.getSelectionDelegate().toggleSelectionForItem(id);
             view.endAnimationsForTests();
-            mBookmarkManagerCoordinator.getToolbarForTesting().endAnimationsForTesting();
+            mToolbar.endAnimationsForTesting();
         });
         RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer);
     }
@@ -1957,4 +1929,8 @@
         runOnUiThreadBlocking(() -> mDelegate.openFolder(folder));
         RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer);
     }
+
+    private void clickToolbarMenuItem(@IdRes int menuId) throws ExecutionException {
+        runOnUiThreadBlocking(() -> mToolbar.onMenuItemClick(mToolbar.getMenu().findItem(menuId)));
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java
index 40e59e2f..b7a9d34 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/app/omnibox/ActionChipsDelegateImplUnitTest.java
@@ -5,12 +5,11 @@
 package org.chromium.chrome.browser.app.omnibox;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -20,8 +19,6 @@
 import android.content.Intent;
 import android.net.Uri;
 
-import androidx.annotation.Nullable;
-
 import com.google.common.collect.ImmutableSet;
 
 import org.junit.After;
@@ -33,30 +30,16 @@
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowLog;
 import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.supplier.OneshotSupplierImpl;
-import org.chromium.base.supplier.Supplier;
 import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.autofill.settings.AutofillPaymentMethodsFragment;
-import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
-import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataTabsFragment;
-import org.chromium.chrome.browser.history_clusters.HistoryClustersCoordinator;
 import org.chromium.chrome.browser.omnibox.suggestions.ActionChipsDelegate;
 import org.chromium.chrome.browser.omnibox.suggestions.SuggestionsMetrics;
-import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher;
-import org.chromium.chrome.browser.safety_check.SafetyCheckSettingsFragment;
-import org.chromium.chrome.browser.settings.SettingsActivity;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.components.browser_ui.accessibility.AccessibilitySettings;
-import org.chromium.components.browser_ui.site_settings.SiteSettings;
+import org.chromium.components.browser_ui.settings.SettingsLauncher;
+import org.chromium.components.browser_ui.settings.SettingsLauncher.SettingsFragment;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.omnibox.EntityInfoProto;
 import org.chromium.components.omnibox.action.HistoryClustersAction;
@@ -66,34 +49,15 @@
 import org.chromium.components.omnibox.action.OmniboxPedal;
 import org.chromium.components.omnibox.action.OmniboxPedalType;
 import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.ui.modaldialog.ModalDialogManager;
 
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Tests for {@link ActionChipsDelegateImpl}.
  */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE,
-        shadows = {ShadowLog.class, ShadowLooper.class,
-                ActionChipsDelegateImplUnitTest.ShadowPasswordManagerLauncher.class})
 public class ActionChipsDelegateImplUnitTest {
-    /** Shadow PasswordManagerLauncher, used to capture Password Manager launch events. */
-    @Implements(PasswordManagerLauncher.class)
-    public static class ShadowPasswordManagerLauncher {
-        public static boolean sPasswordSettingsRequested;
-
-        @Implementation
-        public static void showPasswordSettings(Context context, int referrer,
-                Supplier<ModalDialogManager> modalDialogManagerSupplier, boolean managePasskeys) {
-            sPasswordSettingsRequested = true;
-        }
-
-        public static void reset() {
-            sPasswordSettingsRequested = false;
-        }
-    }
-
     /** List of all supported OmniboxPedalTypes. */
     public static final Set<Integer> SUPPORTED_PEDALS = ImmutableSet.of(
             OmniboxPedalType.CLEAR_BROWSING_DATA, OmniboxPedalType.MANAGE_PASSWORDS,
@@ -107,23 +71,27 @@
             ImmutableSet.of(OmniboxActionType.PEDAL, OmniboxActionType.HISTORY_CLUSTERS);
 
     public @Rule MockitoRule mMockitoRule = MockitoJUnit.rule();
-    private @Mock HistoryClustersCoordinator mHistoryClustersCoordinator;
+    private @Mock Consumer<String> mMockOpenUrl;
+    private @Mock Consumer<String> mMockOpenHistoryClustersUi;
+    private @Mock Runnable mMockOpenIncognitoPage;
+    private @Mock Runnable mMockOpenPasswordSettings;
+    private @Mock SettingsLauncher mMockSettingsLauncher;
     private @Mock Tab mTab;
     private @Mock Context mMockContext;
     private ArgumentCaptor<Intent> mIntentCaptor = ArgumentCaptor.forClass(Intent.class);
 
     private ShadowLooper mShadowLooper;
-    private OneshotSupplierImpl<HistoryClustersCoordinator> mHistoryClustersCoordinatorSupplier;
     private ActionChipsDelegate mDelegate;
 
     @Before
     public void setUp() {
         mShadowLooper = ShadowLooper.shadowMainLooper();
 
-        mHistoryClustersCoordinatorSupplier = new OneshotSupplierImpl<>();
-
-        mDelegate = new ActionChipsDelegateImpl(
-                mMockContext, mHistoryClustersCoordinatorSupplier, () -> mTab);
+        mDelegate = new ActionChipsDelegateImpl(mMockContext,
+                ()
+                        -> mTab,
+                mMockSettingsLauncher, mMockOpenUrl, mMockOpenIncognitoPage,
+                mMockOpenPasswordSettings, mMockOpenHistoryClustersUi);
 
         doReturn(ContextUtils.getApplicationContext()).when(mMockContext).getApplicationContext();
         doReturn(ContextUtils.getApplicationContext().getPackageName())
@@ -134,27 +102,10 @@
 
     @After
     public void cleanUp() {
-        // Other than tests that verify this value (and reset it to its original state) no other
-        // tests should ever trigger PasswordManager.
-        assertFalse(ShadowPasswordManagerLauncher.sPasswordSettingsRequested);
-        // Other than tests that interact with mHistoryClustersCoordinator (and confirm appropriate
-        // calls to be made) no other tests should interact with this instance.
-        verifyNoMoreInteractions(mHistoryClustersCoordinator);
-    }
-
-    /**
-     * Confirm that an intent has been emitted to start a particular Fragment of the Search
-     * activity.
-     *
-     * @param fragmentClass When specified, expect particular settings fragment to be requested.
-     */
-    private void checkSettingsActivityFragmentStarted(@Nullable Class fragmentClass) {
-        verify(mMockContext, times(1)).startActivity(mIntentCaptor.capture(), any());
-
-        var intent = mIntentCaptor.getValue();
-        assertEquals(SettingsActivity.class.getName(), intent.getComponent().getClassName());
-        assertEquals(fragmentClass == null ? null : fragmentClass.getName(),
-                intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT));
+        verifyNoMoreInteractions(mMockOpenIncognitoPage);
+        verifyNoMoreInteractions(mMockOpenPasswordSettings);
+        verifyNoMoreInteractions(mMockOpenHistoryClustersUi);
+        verifyNoMoreInteractions(mMockOpenUrl);
     }
 
     /**
@@ -202,84 +153,76 @@
     @Test
     public void executePedal_manageChromeSettings() {
         mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_CHROME_SETTINGS));
-        checkSettingsActivityFragmentStarted(null);
+        verify(mMockSettingsLauncher).launchSettingsActivity(any(), eq(SettingsFragment.MAIN));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_CHROME_SETTINGS);
     }
 
     @Test
     public void executePedal_clearBrowsingData() {
         mDelegate.execute(buildPedal(OmniboxPedalType.CLEAR_BROWSING_DATA));
-        checkSettingsActivityFragmentStarted(ClearBrowsingDataTabsFragment.class);
+        verify(mMockSettingsLauncher)
+                .launchSettingsActivity(any(), eq(SettingsFragment.CLEAR_BROWSING_DATA));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.CLEAR_BROWSING_DATA);
     }
 
     @Test
     public void executePedal_managePasswords() {
         mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_PASSWORDS));
-        assertTrue(ShadowPasswordManagerLauncher.sPasswordSettingsRequested);
-        ShadowPasswordManagerLauncher.reset();
+        verify(mMockOpenPasswordSettings).run();
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_PASSWORDS);
     }
 
     @Test
     public void executePedal_updateCreditCard() {
         mDelegate.execute(buildPedal(OmniboxPedalType.UPDATE_CREDIT_CARD));
-        checkSettingsActivityFragmentStarted(AutofillPaymentMethodsFragment.class);
+        verify(mMockSettingsLauncher)
+                .launchSettingsActivity(any(), eq(SettingsFragment.PAYMENT_METHODS));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.UPDATE_CREDIT_CARD);
     }
 
     @Test
     public void executePedal_runChromeSafetyCheck() {
         mDelegate.execute(buildPedal(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK));
-        checkSettingsActivityFragmentStarted(SafetyCheckSettingsFragment.class);
+        verify(mMockSettingsLauncher)
+                .launchSettingsActivity(any(), eq(SettingsFragment.SAFETY_CHECK));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.RUN_CHROME_SAFETY_CHECK);
     }
 
     @Test
     public void executePedal_manageSiteSettings() {
         mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_SITE_SETTINGS));
-        checkSettingsActivityFragmentStarted(SiteSettings.class);
+        verify(mMockSettingsLauncher).launchSettingsActivity(any(), eq(SettingsFragment.SITE));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_SITE_SETTINGS);
     }
 
     @Test
     public void executePedal_manageChromeAccessibility() {
         mDelegate.execute(buildPedal(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY));
-        checkSettingsActivityFragmentStarted(AccessibilitySettings.class);
+        verify(mMockSettingsLauncher)
+                .launchSettingsActivity(any(), eq(SettingsFragment.ACCESSIBILITY));
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.MANAGE_CHROME_ACCESSIBILITY);
     }
 
     @Test
-    public void executePedal_launchIncognito_fromCustomActivity() {
+    public void executePedal_launchIncognito() {
         doReturn(false).when(mTab).isUserInteractable();
         mDelegate.execute(buildPedal(OmniboxPedalType.LAUNCH_INCOGNITO));
-
-        verify(mMockContext, times(1)).startActivity(mIntentCaptor.capture());
-        var intent = mIntentCaptor.getValue();
-
-        assertEquals(Intent.ACTION_VIEW, intent.getAction());
-        assertTrue(intent.getBooleanExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false));
-
+        verify(mMockOpenIncognitoPage).run();
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.LAUNCH_INCOGNITO);
     }
 
     @Test
-    public void executePedal_viewChromeHistory_fromCustomActivity() {
+    public void executePedal_viewChromeHistory_nonInteractable() {
         doReturn(false).when(mTab).isUserInteractable();
         mDelegate.execute(buildPedal(OmniboxPedalType.VIEW_CHROME_HISTORY));
 
-        verify(mMockContext, times(1)).startActivity(mIntentCaptor.capture());
-        var intent = mIntentCaptor.getValue();
-
-        assertEquals(Intent.ACTION_VIEW, intent.getAction());
-        assertEquals(UrlConstants.HISTORY_URL, intent.getDataString());
-        assertTrue(
-                intent.getBooleanExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, false));
+        verify(mMockOpenUrl).accept(UrlConstants.HISTORY_URL);
+        checkOmniboxPedalUsageRecorded(OmniboxPedalType.VIEW_CHROME_HISTORY);
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.VIEW_CHROME_HISTORY);
     }
 
     @Test
-    public void executePedal_viewChromeHistory_fromTabbedActivity() {
+    public void executePedal_viewChromeHistory() {
         doReturn(true).when(mTab).isUserInteractable();
         mDelegate.execute(buildPedal(OmniboxPedalType.VIEW_CHROME_HISTORY));
 
@@ -292,37 +235,18 @@
     }
 
     @Test
-    public void executePedal_playChromeDinoGame_fromCustomActivity() {
+    public void executePedal_playChromeDinoGame_nonInteractable() {
         doReturn(false).when(mTab).isUserInteractable();
         mDelegate.execute(buildPedal(OmniboxPedalType.PLAY_CHROME_DINO_GAME));
-
-        verify(mMockContext, times(1)).startActivity(mIntentCaptor.capture());
-        var intent = mIntentCaptor.getValue();
-
-        assertEquals(Intent.ACTION_VIEW, intent.getAction());
-        assertEquals(UrlConstants.CHROME_DINO_URL, intent.getDataString());
-        assertTrue(
-                intent.getBooleanExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, false));
-
+        verify(mMockOpenUrl).accept(UrlConstants.CHROME_DINO_URL);
         checkOmniboxPedalUsageRecorded(OmniboxPedalType.PLAY_CHROME_DINO_GAME);
     }
 
     @Test
-    public void executeHistoryClusters_noCoordinator() {
+    public void executeHistoryClusters() {
         String testJourneyName = "example journey name";
         mDelegate.execute(buildHistoryClustersAction(testJourneyName));
-        verifyNoMoreInteractions(mHistoryClustersCoordinator);
-    }
-
-    @Test
-    public void executeHistoryClusters_withCoordinator() {
-        String testJourneyName = "example journey name";
-
-        mHistoryClustersCoordinatorSupplier.set(mHistoryClustersCoordinator);
-        mShadowLooper.runToEndOfTasks();
-
-        mDelegate.execute(buildHistoryClustersAction(testJourneyName));
-        verify(mHistoryClustersCoordinator).openHistoryClustersUi(testJourneyName);
+        verify(mMockOpenHistoryClustersUi).accept(testJourneyName);
     }
 
     @Test
@@ -428,6 +352,8 @@
         mDelegate.execute(
                 buildActionInSuggest(EntityInfoProto.ActionInfo.ActionType.DIRECTIONS, intent));
 
+        verify(mMockOpenUrl).accept(UrlConstants.CHROME_DINO_URL);
+
         assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         "Android.Omnibox.ActionInSuggest.IntentResult",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
index 49ce333..7708469 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BasicBookmarkQueryHandlerTest.java
@@ -32,7 +32,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-/** Unit tests for {@link BasicBookmarkQueryHandler}. */
+/** Unit tests for {@link BasicmHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -42,17 +42,20 @@
 
     @Mock
     private BookmarkModel mBookmarkModel;
+    @Mock
+    private BookmarkUiPrefs mBookmarkUiPrefs;
+
+    private BasicBookmarkQueryHandler mHandler;
 
     @Before
     public void setup() {
         SharedBookmarkModelMocks.initMocks(mBookmarkModel);
+        mHandler = new BasicBookmarkQueryHandler(mBookmarkModel, mBookmarkUiPrefs);
     }
 
     @Test
     public void testBuildBookmarkListForParent_nonRootFolder() {
-        BookmarkQueryHandler bookmarkQueryHandler = new BasicBookmarkQueryHandler(mBookmarkModel);
-        List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(MOBILE_BOOKMARK_ID);
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(MOBILE_BOOKMARK_ID);
 
         Assert.assertEquals(2, result.size());
         Assert.assertEquals(FOLDER_BOOKMARK_ID_A, result.get(0).getBookmarkItem().getId());
@@ -61,9 +64,8 @@
 
     @Test
     public void testBuildBookmarkListForParent_shopping() {
-        BookmarkQueryHandler bookmarkQueryHandler = new BasicBookmarkQueryHandler(mBookmarkModel);
         List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(BookmarkId.SHOPPING_FOLDER);
+                mHandler.buildBookmarkListForParent(BookmarkId.SHOPPING_FOLDER);
 
         // Both URL_BOOKMARK_ID_B and URL_BOOKMARK_ID_C will be returned as children of
         // BookmarkId.SHOPPING_FOLDER , but only URL_BOOKMARK_ID_B will have a correct meta.
@@ -73,9 +75,8 @@
 
     @Test
     public void testBuildBookmarkListForParent_readingList() {
-        BookmarkQueryHandler bookmarkQueryHandler = new BasicBookmarkQueryHandler(mBookmarkModel);
         List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(READING_LIST_BOOKMARK_ID);
+                mHandler.buildBookmarkListForParent(READING_LIST_BOOKMARK_ID);
 
         Assert.assertEquals(4, result.size());
         // While the getChildIds call will return [D, E], due to the read status, they should get
@@ -88,11 +89,10 @@
 
     @Test
     public void testBuildBookmarkListForSearch() {
-        BookmarkQueryHandler bookmarkQueryHandler = new BasicBookmarkQueryHandler(mBookmarkModel);
         doReturn(Arrays.asList(FOLDER_BOOKMARK_ID_A, URL_BOOKMARK_ID_A))
                 .when(mBookmarkModel)
                 .searchBookmarks("A", 500);
-        List<BookmarkListEntry> result = bookmarkQueryHandler.buildBookmarkListForSearch("A");
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForSearch("A");
         Assert.assertEquals(2, result.size());
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
index f2214ee6..d1f1407 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
@@ -79,6 +79,8 @@
     BookmarkModel mBookmarkModel;
     @Mock
     BookmarkUiPrefs mBookmarkUiPrefs;
+    @Mock
+    View mView;
 
     private Activity mActivity;
     private BookmarkManagerCoordinator mCoordinator;
@@ -126,5 +128,7 @@
         Assert.assertNotNull(mCoordinator.buildAndInitShoppingItemView(parent));
         Assert.assertNotNull(BookmarkManagerCoordinator.buildDividerView(parent));
         Assert.assertNotNull(BookmarkManagerCoordinator.buildShoppingFilterView(parent));
+        Assert.assertNotNull(mCoordinator.buildAndInitCompactImprovedBookmarkRow(parent));
+        Assert.assertNotNull(mCoordinator.buildAndInitVisualImprovedBookmarkRow(parent));
     }
 }
\ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
index 294dd21..84221a1 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
@@ -49,6 +49,7 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
 import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref;
 import org.chromium.chrome.browser.bookmarks.BookmarkUiState.BookmarkUiMode;
+import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -69,6 +70,7 @@
 import org.chromium.components.favicon.IconType;
 import org.chromium.components.favicon.LargeIconBridge;
 import org.chromium.components.favicon.LargeIconBridge.LargeIconCallback;
+import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.components.payments.CurrencyFormatter;
 import org.chromium.components.payments.CurrencyFormatterJni;
 import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
@@ -142,7 +144,7 @@
     @Mock
     private CurrencyFormatter.Natives mCurrencyFormatterJniMock;
     @Mock
-    private SharedPreferencesManager mSharedPrefsManager;
+    private Tracker mTracker;
 
     @Captor
     private ArgumentCaptor<BookmarkModelObserver> mBookmarkModelObserverArgumentCaptor;
@@ -162,6 +164,10 @@
     private final BookmarkId mFolderId2 = new BookmarkId(/*id=*/3, BookmarkType.NORMAL);
     private final BookmarkId mFolderId3 = new BookmarkId(/*id=*/4, BookmarkType.NORMAL);
     private final BookmarkId mBookmarkId21 = new BookmarkId(/*id=*/5, BookmarkType.NORMAL);
+    private final BookmarkId mReadingListFolderId =
+            new BookmarkId(/*id=*/5, BookmarkType.READING_LIST);
+    private final BookmarkId mReadingListId = new BookmarkId(/*id=*/6, BookmarkType.READING_LIST);
+
     private final BookmarkItem mFolderItem1 =
             new BookmarkItem(mFolderId1, "Folder1", null, true, null, true, false, 0, false);
     private final BookmarkItem mFolderItem2 =
@@ -171,6 +177,12 @@
     private final BookmarkItem mBookmarkItem21 = new BookmarkItem(mBookmarkId21, "Bookmark21",
             JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), false, mFolderId1, true, false, 0,
             false);
+    private final BookmarkItem mReadingListFolderItem = new BookmarkItem(mReadingListFolderId,
+            "ReadingList", JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), true, null, false,
+            false, 0, false);
+    private final BookmarkItem mReadingListItem = new BookmarkItem(mReadingListId, "ReadingList",
+            JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), false, mReadingListFolderId, true,
+            false, 0, false);
     private final ModelList mModelList = new ModelList();
     private final Bitmap mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
     private BookmarkUiPrefs mBookmarkUiPrefs =
@@ -197,6 +209,9 @@
             // Setup CurrencyFormatter.
             mJniMocker.mock(CurrencyFormatterJni.TEST_HOOKS, mCurrencyFormatterJniMock);
 
+            // Setup TrackerFactory.
+            TrackerFactory.setTrackerForTests(mTracker);
+
             // Setup BookmarkModel.
             doReturn(mRootFolderId).when(mBookmarkModel).getRootFolderId();
             doReturn(true).when(mBookmarkModel).doesBookmarkExist(any());
@@ -209,6 +224,13 @@
             doReturn(Arrays.asList(mBookmarkId21)).when(mBookmarkModel).getChildIds(mFolderId2);
             doReturn(1).when(mBookmarkModel).getTotalBookmarkCount(mFolderId2);
             doReturn(mFolderItem3).when(mBookmarkModel).getBookmarkById(mFolderId3);
+            doReturn(Arrays.asList(mReadingListId))
+                    .when(mBookmarkModel)
+                    .getChildIds(mReadingListFolderId);
+            doReturn(mReadingListFolderItem)
+                    .when(mBookmarkModel)
+                    .getBookmarkById(mReadingListFolderId);
+            doReturn(mReadingListItem).when(mBookmarkModel).getBookmarkById(mReadingListId);
 
             // Setup SelectableListLayout.
             doReturn(mActivity).when(mSelectableListLayout).getContext();
@@ -421,9 +443,11 @@
     }
 
     @Test
+    @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
     public void onPreferenceChanged_ViewPreferenceUpdated() {
-        mMediator.onBookmarkRowDisplayPrefChanged();
-        verify(mRecyclerView).setAdapter(mDragReorderableRecyclerViewAdapter);
+        mMediator.openFolder(mFolderId1);
+        mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.VISUAL);
+        assertEquals(ViewType.IMPROVED_BOOKMARK_VISUAL, mModelList.get(0).type);
     }
 
     @Test
@@ -433,9 +457,8 @@
         mMediator.openFolder(mFolderId2);
         assertEquals(1, mModelList.size());
 
-        ListItem item = mMediator.buildImprovedBookmarkRow(
-                BookmarkListEntry.createBookmarkEntry(mBookmarkItem21, null), 0);
-        assertEquals(ViewType.IMPROVED_BOOKMARK, item.type);
+        ListItem item = mModelList.get(0);
+        assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
 
         PropertyModel model = item.model;
         assertNotNull(model);
@@ -456,6 +479,33 @@
 
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
+    public void testBuildImprovedBookmarkRow_ReadingList() {
+        finishLoading();
+        mMediator.openFolder(mReadingListFolderId);
+        assertEquals(3, mModelList.size());
+
+        ListItem item = mModelList.get(1);
+        assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
+
+        PropertyModel model = item.model;
+        assertNotNull(model);
+        assertEquals(mReadingListItem,
+                model.get(BookmarkManagerProperties.BOOKMARK_LIST_ENTRY).getBookmarkItem());
+        assertEquals(mReadingListId, model.get(BookmarkManagerProperties.BOOKMARK_ID));
+        assertEquals(mReadingListItem.getTitle(), model.get(ImprovedBookmarkRowProperties.TITLE));
+        assertEquals(
+                "https://www.example.com/", model.get(ImprovedBookmarkRowProperties.DESCRIPTION));
+        assertNotNull(model.get(ImprovedBookmarkRowProperties.ICON));
+        assertNotNull(model.get(ImprovedBookmarkRowProperties.POPUP_LISTENER));
+        assertEquals(false, model.get(ImprovedBookmarkRowProperties.SELECTION_ACTIVE));
+        assertEquals(false, model.get(ImprovedBookmarkRowProperties.DRAG_ENABLED));
+        assertNotNull(model.get(ImprovedBookmarkRowProperties.LIST_MENU));
+        assertEquals(true, model.get(ImprovedBookmarkRowProperties.EDITABLE));
+        assertNotNull(model.get(ImprovedBookmarkRowProperties.OPEN_BOOKMARK_CALLBACK));
+    }
+
+    @Test
+    @EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
     public void testBuildImprovedBookmarkRow_Shopping() {
         ShoppingSpecifics specifics = ShoppingSpecifics.newBuilder()
                                               .setCurrentPrice(ProductPrice.newBuilder()
@@ -477,7 +527,7 @@
         assertEquals(1, mModelList.size());
 
         ListItem item = mModelList.get(0);
-        assertEquals(ViewType.IMPROVED_BOOKMARK, item.type);
+        assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
 
         PropertyModel model = item.model;
         assertNotNull(model);
@@ -492,7 +542,7 @@
         assertEquals(2, mModelList.size());
 
         ListItem item = mModelList.get(0);
-        assertEquals(ViewType.IMPROVED_BOOKMARK, item.type);
+        assertEquals(ViewType.IMPROVED_BOOKMARK_COMPACT, item.type);
 
         PropertyModel model = item.model;
         assertNotNull(model);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefsTest.java
index 3728989..98f0b72 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefsTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefsTest.java
@@ -4,8 +4,9 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -53,7 +54,7 @@
 
     @After
     public void tearDown() {
-        mSharedPreferencesManager.removeKey(ChromePreferenceKeys.BOOKMARK_VISUALS_PREF);
+        mSharedPreferencesManager.removeKey(ChromePreferenceKeys.BOOKMARKS_VISUALS_PREF);
     }
 
     @Test
@@ -102,11 +103,11 @@
     public void setBookmarkRowDisplayPref() {
         mBookmarkUiPrefs.addObserver(mObserver);
         mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.COMPACT);
-        verify(mObserver).onBookmarkRowDisplayPrefChanged();
+        verify(mObserver).onBookmarkRowDisplayPrefChanged(BookmarkRowDisplayPref.COMPACT);
 
+        reset(mObserver);
         mBookmarkUiPrefs.removeObserver(mObserver);
         mBookmarkUiPrefs.setBookmarkRowDisplayPref(BookmarkRowDisplayPref.COMPACT);
-        // The observer method shouldn't have been called again.
-        verify(mObserver, times(1)).onBookmarkRowDisplayPrefChanged();
+        verifyNoInteractions(mObserver);
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
index c506e0c..965abdd5 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java
@@ -30,7 +30,7 @@
 
 import java.util.List;
 
-/** Unit tests for {@link ImprovedBookmarkQueryHandler}. */
+/** Unit tests for {@link ImprovedmHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -41,23 +41,26 @@
     @Mock
     private BookmarkModel mBookmarkModel;
     @Mock
-    Tracker mTracker;
+    private Tracker mTracker;
     @Mock
-    Profile mProfile;
+    private Profile mProfile;
+    @Mock
+    private BookmarkUiPrefs mBookmarkUiPrefs;
+
+    private ImprovedBookmarkQueryHandler mHandler;
 
     @Before
     public void setup() {
         Profile.setLastUsedProfileForTesting(mProfile);
         TrackerFactory.setTrackerForTests(mTracker);
         SharedBookmarkModelMocks.initMocks(mBookmarkModel);
+
+        mHandler = new ImprovedBookmarkQueryHandler(mBookmarkModel, mBookmarkUiPrefs);
     }
 
     @Test
     public void testBuildBookmarkListForParent_rootFolder() {
-        BookmarkQueryHandler bookmarkQueryHandler =
-                new ImprovedBookmarkQueryHandler(mBookmarkModel);
-        List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
         Assert.assertEquals(6, result.size());
         Assert.assertEquals(DESKTOP_BOOKMARK_ID, result.get(0).getBookmarkItem().getId());
         Assert.assertEquals(FOLDER_BOOKMARK_ID_A, result.get(1).getBookmarkItem().getId());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
index 4f2083d..b9764da 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
@@ -50,6 +50,8 @@
     @Mock
     View mView;
     @Mock
+    ViewGroup mViewGroup;
+    @Mock
     ListMenu mListMenu;
     @Mock
     Runnable mPopupListener;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
index 3960636e..68669b78 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java
@@ -47,10 +47,11 @@
 import java.util.Arrays;
 import java.util.List;
 
-/** Unit tests for {@link LegacyBookmarkQueryHandler}. */
+/** Unit tests for {@link LegacymHandler}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
+@EnableFeatures(ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS)
 @DisableFeatures(ChromeFeatureList.SHOPPING_LIST)
 public class LegacyBookmarkQueryHandlerTest {
     @Rule
@@ -63,42 +64,45 @@
     @Mock
     private SyncService mSyncService;
     @Mock
-    Tracker mTracker;
+    private Tracker mTracker;
     @Mock
-    Profile mProfile;
+    private Profile mProfile;
+    @Mock
+    private BookmarkUiPrefs mBookmarkUiPrefs;
 
     @Captor
     private ArgumentCaptor<Runnable> mFinishLoadingBookmarkModelCaptor;
     @Captor
     private ArgumentCaptor<SyncStateChangedListener> mSyncStateChangedListenerCaptor;
 
+    private LegacyBookmarkQueryHandler mHandler;
+
     @Before
     public void setup() {
         SyncService.overrideForTests(mSyncService);
         TrackerFactory.setTrackerForTests(mTracker);
         Profile.setLastUsedProfileForTesting(mProfile);
         SharedBookmarkModelMocks.initMocks(mBookmarkModel);
+
+        mHandler = new LegacyBookmarkQueryHandler(mBookmarkModel, mBookmarkUiPrefs);
     }
 
     @Test
     public void testDestroy() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
         verify(mSyncService).addSyncStateChangedListener(any());
 
-        bookmarkQueryHandler.destroy();
+        mHandler.destroy();
         verify(mSyncService).removeSyncStateChangedListener(any());
     }
 
     @Test
     public void testBuildBookmarkListForParent_rootFolder_isFolderVisible() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
         verify(mBookmarkModel)
                 .finishLoadingBookmarkModel(mFinishLoadingBookmarkModelCaptor.capture());
         doReturn(true).when(mBookmarkModel).isBookmarkModelLoaded();
         mFinishLoadingBookmarkModelCaptor.getValue().run();
 
-        List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
         assertEquals(3, result.size());
 
         doReturn(true).when(mBookmarkModel).isFolderVisible(OTHER_BOOKMARK_ID);
@@ -106,48 +110,45 @@
         mSyncStateChangedListenerCaptor.getValue().syncStateChanged();
 
         List<BookmarkListEntry> updatedResult =
-                bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
+                mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
         assertEquals(4, updatedResult.size());
     }
 
     @Test
     public void testBuildBookmarkListForParent_rootFolder_isBookmarkModelLoaded() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
         verify(mSyncService).addSyncStateChangedListener(mSyncStateChangedListenerCaptor.capture());
         mSyncStateChangedListenerCaptor.getValue().syncStateChanged();
 
-        assertTrue(bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID).isEmpty());
+        assertTrue(mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID).isEmpty());
 
         doReturn(true).when(mBookmarkModel).isBookmarkModelLoaded();
         mSyncStateChangedListenerCaptor.getValue().syncStateChanged();
 
-        assertFalse(bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID).isEmpty());
+        assertFalse(mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID).isEmpty());
     }
 
     @Test
     @EnableFeatures(ChromeFeatureList.SHOPPING_LIST)
     public void testBuildBookmarkListForParent_rootFolder_withShopping() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
         verify(mBookmarkModel)
                 .finishLoadingBookmarkModel(mFinishLoadingBookmarkModelCaptor.capture());
         doReturn(true).when(mBookmarkModel).isBookmarkModelLoaded();
         mFinishLoadingBookmarkModelCaptor.getValue().run();
 
-        List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID);
         assertEquals(5, result.size());
         assertEquals(READING_LIST_BOOKMARK_ID, result.get(0).getBookmarkItem().getId());
         assertEquals(MOBILE_BOOKMARK_ID, result.get(1).getBookmarkItem().getId());
         assertEquals(DESKTOP_BOOKMARK_ID, result.get(2).getBookmarkItem().getId());
         assertEquals(ViewType.DIVIDER, result.get(3).getViewType());
         assertEquals(ViewType.SHOPPING_FILTER, result.get(4).getViewType());
+
+        assertFalse(mHandler.buildBookmarkListForParent(ROOT_BOOKMARK_ID).isEmpty());
     }
 
     @Test
     public void testBuildBookmarkListForParent_nonRootFolder() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
-        List<BookmarkListEntry> result =
-                bookmarkQueryHandler.buildBookmarkListForParent(MOBILE_BOOKMARK_ID);
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForParent(MOBILE_BOOKMARK_ID);
 
         assertEquals(2, result.size());
         assertEquals(FOLDER_BOOKMARK_ID_A, result.get(0).getBookmarkItem().getId());
@@ -156,11 +157,10 @@
 
     @Test
     public void testBuildBookmarkListForSearch() {
-        BookmarkQueryHandler bookmarkQueryHandler = new LegacyBookmarkQueryHandler(mBookmarkModel);
         doReturn(Arrays.asList(FOLDER_BOOKMARK_ID_A, URL_BOOKMARK_ID_A))
                 .when(mBookmarkModel)
                 .searchBookmarks("A", 500);
-        List<BookmarkListEntry> result = bookmarkQueryHandler.buildBookmarkListForSearch("A");
+        List<BookmarkListEntry> result = mHandler.buildBookmarkListForSearch("A");
         assertEquals(2, result.size());
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
index e2a24d0..4500c6d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
@@ -43,7 +43,7 @@
         BookmarkId bookmarkId = new BookmarkId(id, BookmarkType.READING_LIST);
         BookmarkItem bookmarkItem = new BookmarkItem(
                 bookmarkId, null, null, false, null, false, false, dateAdded, read);
-        return BookmarkListEntry.createBookmarkEntry(bookmarkItem, /*powerBookmarkMeta=*/null);
+        return BookmarkListEntry.createBookmarkEntry(bookmarkItem, /*powerBookmarkMeta=*/null, 0);
     }
 
     private BookmarkListEntry createReadingListEntry(long id, boolean read) {
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 885004c..dedd701 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-115.0.5751.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-115.0.5752.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app_shim/app_shim_controller.mm b/chrome/app_shim/app_shim_controller.mm
index 18948d0..18108af 100644
--- a/chrome/app_shim/app_shim_controller.mm
+++ b/chrome/app_shim/app_shim_controller.mm
@@ -235,14 +235,14 @@
       chrome_bundle_path, browser_command_line, /*url_specs=*/{},
       {.create_new_instance = true},
       base::BindOnce(
-          [](AppShimController* shim_controller,
-             base::expected<NSRunningApplication*, NSError*> result) {
-            if (!result.has_value()) {
+          [](AppShimController* shim_controller, NSRunningApplication* app,
+             NSError* error) {
+            if (error) {
               LOG(FATAL) << "Failed to launch Chrome.";
             }
 
             shim_controller->chrome_launched_by_app_.reset(
-                result.value(), base::scoped_policy::RETAIN);
+                app, base::scoped_policy::RETAIN);
 
             // Start polling to see if Chrome is ready to connect.
             shim_controller->PollForChromeReady(kPollTimeoutSeconds);
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 9d864559..7cc0bedc 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2795,12 +2795,8 @@
       "android/profile_key_startup_accessor.h",
       "android/profile_key_util.cc",
       "android/profile_key_util.h",
-      "android/reading_list/reading_list_bridge.cc",
-      "android/reading_list/reading_list_bridge.h",
       "android/reading_list/reading_list_manager_factory.cc",
       "android/reading_list/reading_list_manager_factory.h",
-      "android/reading_list/reading_list_notification_service_factory.cc",
-      "android/reading_list/reading_list_notification_service_factory.h",
       "android/recently_closed_tabs_bridge.cc",
       "android/recently_closed_tabs_bridge.h",
       "android/renderer_host/chrome_navigation_ui_data_android.cc",
@@ -3294,6 +3290,7 @@
       "//chrome/browser/password_manager:password_manager_buildflags",
       "//chrome/browser/password_manager/android:backend_public",
       "//chrome/browser/password_manager/android:jni_headers",
+      "//chrome/browser/password_manager/android/pwd_migration:utils",
       "//chrome/browser/payments/android:jni_headers",
       "//chrome/browser/policy/android:android",
       "//chrome/browser/policy/android:jni_headers",
@@ -3393,6 +3390,7 @@
       "//components/signin/internal/identity_manager",  # cf android/signin/DEPS
       "//components/signin/public/android:jni_headers",
       "//components/subresource_filter/android",
+      "//components/supervised_user/core/browser:fetcher",
       "//components/thin_webview/internal",
       "//components/translate/content/android",
       "//components/translate/core/language_detection",
@@ -7505,6 +7503,7 @@
     deps += [
       "//chrome/common:supervised_user_commands_mojom",
       "//components/supervised_user/core/browser",
+      "//components/supervised_user/core/browser:fetcher",
       "//components/supervised_user/core/browser/proto",
       "//components/supervised_user/core/common",
     ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 402e6d4..1d9eb62 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3327,6 +3327,45 @@
          kTimeBeforeDiscardInMinutesSwitch,
      "720"},
 };
+
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithRing30Opacity[] = {
+    {"discard_tab_treatment_option", "2"},
+    {"discard_tab_treatment_opacity", "0.3"}};
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithRing40Opacity[] = {
+    {"discard_tab_treatment_option", "2"},
+    {"discard_tab_treatment_opacity", "0.4"}};
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithRing50Opacity[] = {
+    {"discard_tab_treatment_option", "2"},
+    {"discard_tab_treatment_opacity", "0.5"}};
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithoutRing30Opacity[] =
+    {{"discard_tab_treatment_option", "1"},
+     {"discard_tab_treatment_opacity", "0.3"}};
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithoutRing40Opacity[] =
+    {{"discard_tab_treatment_option", "1"},
+     {"discard_tab_treatment_opacity", "0.4"}};
+const FeatureEntry::FeatureParam kDiscardedTabTreatmentWithoutRing50Opacity[] =
+    {{"discard_tab_treatment_option", "1"},
+     {"discard_tab_treatment_opacity", "0.5"}};
+
+const FeatureEntry::FeatureVariation kDiscardedTabTreatmentVariations[] = {
+    {"With Ring and 30\% Opacity", kDiscardedTabTreatmentWithRing30Opacity,
+     std::size(kDiscardedTabTreatmentWithRing30Opacity), nullptr},
+    {"With Ring and 40\% Opacity", kDiscardedTabTreatmentWithRing40Opacity,
+     std::size(kDiscardedTabTreatmentWithRing40Opacity), nullptr},
+    {"With Ring and 50\% Opacity", kDiscardedTabTreatmentWithRing50Opacity,
+     std::size(kDiscardedTabTreatmentWithRing50Opacity), nullptr},
+    {"Without Ring and 30\% Opacity",
+     kDiscardedTabTreatmentWithoutRing30Opacity,
+     std::size(kDiscardedTabTreatmentWithoutRing30Opacity), nullptr},
+    {"Without Ring and 40\% Opacity",
+     kDiscardedTabTreatmentWithoutRing40Opacity,
+     std::size(kDiscardedTabTreatmentWithoutRing40Opacity), nullptr},
+    {"Without Ring and 50\% Opacity",
+     kDiscardedTabTreatmentWithoutRing50Opacity,
+     std::size(kDiscardedTabTreatmentWithoutRing50Opacity), nullptr},
+
+};
+
 #endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -6119,14 +6158,6 @@
      FEATURE_VALUE_TYPE(features::kQuickSettingsPWANotifications)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if BUILDFLAG(IS_ANDROID)
-    {"read-later-reminder-notification",
-     flag_descriptions::kReadLaterReminderNotificationName,
-     flag_descriptions::kReadLaterReminderNotificationDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(
-         reading_list::switches::kReadLaterReminderNotification)},
-#endif
-
     {"tab-groups-save", flag_descriptions::kTabGroupsSaveName,
      flag_descriptions::kTabGroupsSaveDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kTabGroupsSave)},
@@ -9543,6 +9574,15 @@
      flag_descriptions::kHighEfficiencyModeTimeBeforeDiscardDescription,
      kOsDesktop, MULTI_VALUE_TYPE(kHighEfficiencyModeTimeBeforeDiscardChoices)},
 
+    {"memory-saver-discarded-tab-treatment",
+     flag_descriptions::kHighEfficiencyDiscardedTabTreatmentName,
+     flag_descriptions::kHighEfficiencyDiscardedTabTreatmentDescription,
+     kOsDesktop,
+     FEATURE_WITH_PARAMS_VALUE_TYPE(
+         performance_manager::features::kDiscardedTabTreatment,
+         kDiscardedTabTreatmentVariations,
+         "DiscardedTabTreatment")},
+
     {"memory-saver-savings-reporting-improvements",
      flag_descriptions::kHighEfficiencySavingsReportingImprovementsName,
      flag_descriptions::kHighEfficiencySavingsReportingImprovementsDescription,
diff --git a/chrome/browser/android/reading_list/reading_list_bridge.cc b/chrome/browser/android/reading_list/reading_list_bridge.cc
deleted file mode 100644
index 057f342..0000000
--- a/chrome/browser/android/reading_list/reading_list_bridge.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/reading_list/reading_list_bridge.h"
-
-#include "base/android/jni_string.h"
-#include "chrome/android/chrome_jni_headers/ReadingListBridge_jni.h"
-#include "chrome/browser/android/reading_list/reading_list_notification_service_factory.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-
-// static
-void JNI_ReadingListBridge_OnStartChromeForeground(JNIEnv* env) {
-  if (!ReadingListNotificationService::IsEnabled())
-    return;
-
-  Profile* profile = ProfileManager::GetLastUsedProfile();
-  auto* service =
-      ReadingListNotificationServiceFactory::GetForBrowserContext(profile);
-  service->OnStart();
-}
-
-std::u16string ReadingListBridge::getNotificationTitle() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  std::u16string title;
-  base::android::ConvertJavaStringToUTF16(
-      env, Java_ReadingListBridge_getNotificationTitle(env).obj(), &title);
-  return title;
-}
-
-std::u16string ReadingListBridge::getNotificationSubTitle(int unread_size) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  std::u16string subtitle;
-  base::android::ConvertJavaStringToUTF16(
-      env, Java_ReadingListBridge_getNotificationText(env, unread_size).obj(),
-      &subtitle);
-  return subtitle;
-}
-
-void ReadingListBridge::OpenReadingListPage() {
-  if (!ReadingListNotificationService::IsEnabled())
-    return;
-
-  Java_ReadingListBridge_openReadingListPage(
-      base::android::AttachCurrentThread());
-}
diff --git a/chrome/browser/android/reading_list/reading_list_bridge.h b/chrome/browser/android/reading_list/reading_list_bridge.h
deleted file mode 100644
index fe16113..0000000
--- a/chrome/browser/android/reading_list/reading_list_bridge.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_BRIDGE_H_
-#define CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_BRIDGE_H_
-
-#include "chrome/browser/reading_list/android/reading_list_notification_delegate.h"
-
-class ReadingListBridge : public ReadingListNotificationDelegate {
- public:
-  ReadingListBridge() = default;
-  ~ReadingListBridge() override = default;
-
- private:
-  // ReadingListNotificationDelegate implementation.
-  std::u16string getNotificationTitle() override;
-  std::u16string getNotificationSubTitle(int unread_size) override;
-  void OpenReadingListPage() override;
-};
-
-#endif  // CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_BRIDGE_H_
diff --git a/chrome/browser/android/reading_list/reading_list_notification_service_factory.cc b/chrome/browser/android/reading_list/reading_list_notification_service_factory.cc
deleted file mode 100644
index b90fe14..0000000
--- a/chrome/browser/android/reading_list/reading_list_notification_service_factory.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/reading_list/reading_list_notification_service_factory.h"
-
-#include <memory>
-
-#include "base/time/default_clock.h"
-#include "chrome/browser/android/reading_list/reading_list_bridge.h"
-#include "chrome/browser/notifications/scheduler/notification_schedule_service_factory.h"
-#include "chrome/browser/profiles/incognito_helpers.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_key.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-#include "chrome/browser/reading_list/reading_list_model_factory.h"
-#include "components/reading_list/features/reading_list_switches.h"
-
-// static
-ReadingListNotificationServiceFactory*
-ReadingListNotificationServiceFactory::GetInstance() {
-  return base::Singleton<ReadingListNotificationServiceFactory>::get();
-}
-
-// static
-ReadingListNotificationService*
-ReadingListNotificationServiceFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<ReadingListNotificationService*>(
-      GetInstance()->GetServiceForBrowserContext(context, /*create=*/true));
-}
-
-ReadingListNotificationServiceFactory::ReadingListNotificationServiceFactory()
-    : ProfileKeyedServiceFactory(
-          "ReadingListNotificationService",
-          ProfileSelections::BuildRedirectedInIncognito()) {
-  DependsOn(ReadingListModelFactory::GetInstance());
-  DependsOn(NotificationScheduleServiceFactory::GetInstance());
-}
-
-ReadingListNotificationServiceFactory::
-    ~ReadingListNotificationServiceFactory() = default;
-
-KeyedService* ReadingListNotificationServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  auto* reading_list_model =
-      ReadingListModelFactory::GetForBrowserContext(context);
-  Profile* profile = Profile::FromBrowserContext(context);
-  auto* notification_scheduler =
-      NotificationScheduleServiceFactory::GetForKey(profile->GetProfileKey());
-  auto config = std::make_unique<ReadingListNotificationService::Config>();
-  config->notification_show_time = 8;
-  return new ReadingListNotificationServiceImpl(
-      reading_list_model, notification_scheduler,
-      std::make_unique<ReadingListBridge>(), std::move(config),
-      base::DefaultClock::GetInstance());
-}
diff --git a/chrome/browser/android/reading_list/reading_list_notification_service_factory.h b/chrome/browser/android/reading_list/reading_list_notification_service_factory.h
deleted file mode 100644
index 04fe3d54..0000000
--- a/chrome/browser/android/reading_list/reading_list_notification_service_factory.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_NOTIFICATION_SERVICE_FACTORY_H_
-#define CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_NOTIFICATION_SERVICE_FACTORY_H_
-
-#include "base/memory/singleton.h"
-#include "chrome/browser/profiles/profile_keyed_service_factory.h"
-
-class ReadingListNotificationService;
-
-// A factory to create the ReadingListManager singleton.
-class ReadingListNotificationServiceFactory
-    : public ProfileKeyedServiceFactory {
- public:
-  static ReadingListNotificationServiceFactory* GetInstance();
-  static ReadingListNotificationService* GetForBrowserContext(
-      content::BrowserContext* context);
-
- private:
-  friend struct base::DefaultSingletonTraits<
-      ReadingListNotificationServiceFactory>;
-
-  ReadingListNotificationServiceFactory();
-  ~ReadingListNotificationServiceFactory() override;
-
-  ReadingListNotificationServiceFactory(
-      const ReadingListNotificationServiceFactory&) = delete;
-  ReadingListNotificationServiceFactory& operator=(
-      const ReadingListNotificationServiceFactory&) = delete;
-
-  // BrowserContextKeyedServiceFactory overrides.
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const override;
-};
-
-#endif  // CHROME_BROWSER_ANDROID_READING_LIST_READING_LIST_NOTIFICATION_SERVICE_FACTORY_H_
diff --git a/chrome/browser/apps/platform_apps/app_shim_interactive_uitest_mac.mm b/chrome/browser/apps/platform_apps/app_shim_interactive_uitest_mac.mm
index abe4ccaf..013b826 100644
--- a/chrome/browser/apps/platform_apps/app_shim_interactive_uitest_mac.mm
+++ b/chrome/browser/apps/platform_apps/app_shim_interactive_uitest_mac.mm
@@ -361,12 +361,11 @@
     base::CommandLine shim_cmdline(base::CommandLine::NO_PROGRAM);
     shim_cmdline.AppendSwitch(app_mode::kLaunchedForTest);
 
-    base::test::TestFuture<base::expected<NSRunningApplication*, NSError*>>
-        open_result;
+    base::test::TestFuture<NSRunningApplication*, NSError*> open_result;
     base::mac::LaunchApplication(shim_path_, shim_cmdline, /*url_specs=*/{},
                                  /*options=*/{}, open_result.GetCallback());
-    ASSERT_TRUE(open_result.Get<0>().has_value());
-    NSRunningApplication* shim_app = open_result.Get<0>().value();
+    ASSERT_TRUE(open_result.Get<0>());
+    NSRunningApplication* shim_app = open_result.Get<0>();
     ASSERT_TRUE(shim_app);
 
     base::Process shim_process(shim_app.processIdentifier);
@@ -438,12 +437,11 @@
     base::CommandLine shim_cmdline(base::CommandLine::NO_PROGRAM);
     shim_cmdline.AppendSwitch(app_mode::kLaunchedForTest);
 
-    base::test::TestFuture<base::expected<NSRunningApplication*, NSError*>>
-        open_result;
+    base::test::TestFuture<NSRunningApplication*, NSError*> open_result;
     base::mac::LaunchApplication(shim_path_, shim_cmdline, /*url_specs=*/{},
                                  /*options=*/{}, open_result.GetCallback());
-    ASSERT_TRUE(open_result.Get<0>().has_value());
-    NSRunningApplication* shim_app = open_result.Get<0>().value();
+    ASSERT_TRUE(open_result.Get<0>());
+    NSRunningApplication* shim_app = open_result.Get<0>();
     ASSERT_TRUE(shim_app);
 
     base::Process shim_process(shim_app.processIdentifier);
@@ -664,12 +662,11 @@
   ExtensionTestMessageListener launched_listener("Launched");
   base::CommandLine shim_cmdline(base::CommandLine::NO_PROGRAM);
 
-  base::test::TestFuture<base::expected<NSRunningApplication*, NSError*>>
-      open_result;
+  base::test::TestFuture<NSRunningApplication*, NSError*> open_result;
   base::mac::LaunchApplication(shim_path, shim_cmdline, /*url_specs=*/{},
                                /*options=*/{}, open_result.GetCallback());
-  ASSERT_TRUE(open_result.Get<0>().has_value());
-  NSRunningApplication* shim_app = open_result.Get<0>().value();
+  ASSERT_TRUE(open_result.Get<0>());
+  NSRunningApplication* shim_app = open_result.Get<0>();
   ASSERT_TRUE(shim_app);
 
   // Wait for the app to start (1). At this point there is no shim host.
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index c5fcbbd..0cee8d4 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -1538,8 +1538,6 @@
     "lock_screen_apps/toast_dialog_view.h",
     "logging.cc",
     "logging.h",
-    "login/active_directory_migration_utils.cc",
-    "login/active_directory_migration_utils.h",
     "login/app_mode/force_install_observer.cc",
     "login/app_mode/force_install_observer.h",
     "login/app_mode/kiosk_launch_controller.cc",
diff --git a/chrome/browser/ash/events/event_rewriter_delegate_impl.cc b/chrome/browser/ash/events/event_rewriter_delegate_impl.cc
index 129d47a5..eca55c96 100644
--- a/chrome/browser/ash/events/event_rewriter_delegate_impl.cc
+++ b/chrome/browser/ash/events/event_rewriter_delegate_impl.cc
@@ -91,7 +91,7 @@
   const mojom::KeyboardSettings* settings =
       input_device_settings_controller_->GetKeyboardSettings(device_id);
   if (!settings) {
-    return modifier_key;
+    return absl::nullopt;
   }
 
   auto iter = settings->modifier_remappings.find(modifier_key);
diff --git a/chrome/browser/ash/events/event_rewriter_unittest.cc b/chrome/browser/ash/events/event_rewriter_unittest.cc
index 6a02a26e..4344681 100644
--- a/chrome/browser/ash/events/event_rewriter_unittest.cc
+++ b/chrome/browser/ash/events/event_rewriter_unittest.cc
@@ -201,17 +201,30 @@
     auto deprecation_controller =
         std::make_unique<DeprecationNotificationController>(&message_center_);
     deprecation_controller_ = deprecation_controller.get();
+    ChromeAshTestBase::SetUp();
+
+    input_device_settings_controller_resetter_ = std::make_unique<
+        InputDeviceSettingsController::ScopedResetterForTest>();
+    input_device_settings_controller_mock_ =
+        std::make_unique<MockInputDeviceSettingsController>();
+    keyboard_settings = mojom::KeyboardSettings::New();
+    EXPECT_CALL(*input_device_settings_controller_mock_,
+                GetKeyboardSettings(testing::_))
+        .WillRepeatedly(testing::Return(keyboard_settings.get()));
+
     delegate_ = std::make_unique<EventRewriterDelegateImpl>(
-        nullptr, std::move(deprecation_controller), nullptr);
+        nullptr, std::move(deprecation_controller),
+        input_device_settings_controller_mock_.get());
     delegate_->set_pref_service_for_testing(prefs());
     device_data_manager_test_api_.SetKeyboardDevices({});
     rewriter_ = std::make_unique<ui::EventRewriterAsh>(
         delegate_.get(), keyboard_capability_.get(), nullptr, false,
         &fake_ime_keyboard_);
-    ChromeAshTestBase::SetUp();
   }
 
   void TearDown() override {
+    input_device_settings_controller_mock_.reset();
+    input_device_settings_controller_resetter_.reset();
     ChromeAshTestBase::TearDown();
     // Shutdown() deletes the IME mock object.
     input_method::Shutdown();
@@ -241,10 +254,23 @@
 
   void InitModifierKeyPref(IntegerPrefMember* int_pref,
                            const std::string& pref_name,
-                           ui::mojom::ModifierKey modifierKey) {
-    if (int_pref->GetPrefName() != pref_name)  // skip if already initialized.
-      int_pref->Init(pref_name, prefs());
-    int_pref->SetValue(static_cast<int>(modifierKey));
+                           ui::mojom::ModifierKey remap_from,
+                           ui::mojom::ModifierKey remap_to) {
+    if (!features::IsInputDeviceSettingsSplitEnabled()) {
+      if (int_pref->GetPrefName() !=
+          pref_name) {  // skip if already initialized.
+        int_pref->Init(pref_name, prefs());
+      }
+      int_pref->SetValue(static_cast<int>(remap_to));
+      return;
+    }
+
+    if (remap_from == remap_to) {
+      keyboard_settings->modifier_remappings.erase(remap_from);
+      return;
+    }
+
+    keyboard_settings->modifier_remappings[remap_from] = remap_to;
   }
 
   ui::KeyboardDevice SetupKeyboard(
@@ -382,6 +408,11 @@
       input_method_manager_mock_;
   testing::FakeUdevLoader fake_udev_;
   ui::DeviceDataManagerTestApi device_data_manager_test_api_;
+  std::unique_ptr<InputDeviceSettingsController::ScopedResetterForTest>
+      input_device_settings_controller_resetter_;
+  std::unique_ptr<MockInputDeviceSettingsController>
+      input_device_settings_controller_mock_;
+  mojom::KeyboardSettingsPtr keyboard_settings;
 
   sync_preferences::TestingPrefServiceSyncable prefs_;
   std::unique_ptr<EventRewriterDelegateImpl> delegate_;
@@ -414,6 +445,10 @@
 }
 
 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
+  // This test is not useful once device settings split is launched.
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kInputDeviceSettingsSplit);
+
   // First, test non Apple keyboards, they should all behave the same.
   TestNonAppleKeyboardVariants({
       // VKEY_A, Alt modifier.
@@ -496,6 +531,7 @@
   // Now simulate the user remapped the Command key back to Search.
   IntegerPrefMember command;
   InitModifierKeyPref(&command, ::prefs::kLanguageRemapExternalCommandKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kMeta);
 
   TestExternalAppleKeyboard({
@@ -534,6 +570,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kAlt);
 
   delegate_->SuppressModifierKeyRewrites(false);
@@ -558,6 +595,10 @@
 }
 
 TEST_F(EventRewriterTest, TestRewriteExternalMetaKey) {
+  // This test is irrelevant once input device settings split launches.
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kInputDeviceSettingsSplit);
+
   // Simulate the default initialization of the Meta key on external keyboards
   // remap pref to Search.
   Preferences::RegisterProfilePrefs(prefs()->registry());
@@ -601,11 +642,13 @@
   // Remap Chrome OS Search to Ctrl.
   IntegerPrefMember internal_search;
   InitModifierKeyPref(&internal_search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kControl);
 
   // Remap external Meta to Alt.
   IntegerPrefMember meta;
   InitModifierKeyPref(&meta, ::prefs::kLanguageRemapExternalMetaKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kAlt);
 
   TestChromeKeyboardVariants({
@@ -671,10 +714,15 @@
 
 // For crbug.com/133896.
 TEST_F(EventRewriterTest, TestRewriteCommandToControlWithControlRemapped) {
+  // This test is irrelevant once input device settings split launches.
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kInputDeviceSettingsSplit);
+
   // Remap Control to Alt.
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kAlt);
 
   TestNonAppleKeyboardVariants({
@@ -885,6 +933,11 @@
   // Ctrl.
   Preferences::RegisterProfilePrefs(prefs()->registry());
 
+  if (features::IsInputDeviceSettingsSplitEnabled()) {
+    keyboard_settings->modifier_remappings[ui::mojom::ModifierKey::kMeta] =
+        ui::mojom::ModifierKey::kControl;
+  }
+
   TestExternalAppleKeyboard({
       // XK_KP_End (= NumPad 1 without Num Lock), Win modifier.
       // The result should be "Num Pad 1 with Control + Num Lock modifiers".
@@ -1010,12 +1063,15 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kVoid);
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kVoid);
   IntegerPrefMember escape;
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kVoid);
 
   TestChromeKeyboardVariants({
@@ -1074,6 +1130,7 @@
   // Remap Alt to Control.
   IntegerPrefMember alt;
   InitModifierKeyPref(&alt, ::prefs::kLanguageRemapAltKeyTo,
+                      ui::mojom::ModifierKey::kAlt,
                       ui::mojom::ModifierKey::kControl);
 
   TestChromeKeyboardVariants({
@@ -1099,6 +1156,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kControl);
 
   TestChromeKeyboardVariants({
@@ -1113,6 +1171,7 @@
   // Remap Alt to Control too.
   IntegerPrefMember alt;
   InitModifierKeyPref(&alt, ::prefs::kLanguageRemapAltKeyTo,
+                      ui::mojom::ModifierKey::kAlt,
                       ui::mojom::ModifierKey::kControl);
 
   TestChromeKeyboardVariants({
@@ -1164,6 +1223,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kEscape);
 
   TestChromeKeyboardVariants({
@@ -1180,6 +1240,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember escape;
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kAlt);
 
   TestAllKeyboardVariants({
@@ -1200,6 +1261,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember alt;
   InitModifierKeyPref(&alt, ::prefs::kLanguageRemapAltKeyTo,
+                      ui::mojom::ModifierKey::kAlt,
                       ui::mojom::ModifierKey::kControl);
 
   TestAllKeyboardVariants({
@@ -1231,16 +1293,19 @@
   // Remap Escape to Alt.
   IntegerPrefMember escape;
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kAlt);
 
   // Remap Alt to Control.
   IntegerPrefMember alt;
   InitModifierKeyPref(&alt, ::prefs::kLanguageRemapAltKeyTo,
+                      ui::mojom::ModifierKey::kAlt,
                       ui::mojom::ModifierKey::kControl);
 
   // Remap Control to Search.
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kMeta);
 
   TestAllKeyboardVariants({
@@ -1288,21 +1353,25 @@
   // Remap Escape to Alt.
   IntegerPrefMember escape;
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kAlt);
 
   // Remap Alt to Control.
   IntegerPrefMember alt;
   InitModifierKeyPref(&alt, ::prefs::kLanguageRemapAltKeyTo,
+                      ui::mojom::ModifierKey::kAlt,
                       ui::mojom::ModifierKey::kControl);
 
   // Remap Control to Search.
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kMeta);
 
   // Remap Search to Backspace.
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kBackspace);
 
   TestChromeKeyboardVariants({
@@ -1339,6 +1408,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember backspace;
   InitModifierKeyPref(&backspace, ::prefs::kLanguageRemapBackspaceKeyTo,
+                      ui::mojom::ModifierKey::kBackspace,
                       ui::mojom::ModifierKey::kEscape);
 
   TestAllKeyboardVariants({
@@ -1356,6 +1426,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember escape;
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kAlt);
 
   SetupKeyboard("Internal Keyboard");
@@ -1371,6 +1442,7 @@
 
   // Remap Escape to Control before releasing Escape.
   InitModifierKeyPref(&escape, ::prefs::kLanguageRemapEscapeKeyTo,
+                      ui::mojom::ModifierKey::kEscape,
                       ui::mojom::ModifierKey::kControl);
 
   // Release Escape.
@@ -1406,6 +1478,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapSearchKeyTo,
+                      ui::mojom::ModifierKey::kMeta,
                       ui::mojom::ModifierKey::kCapsLock);
 
   SetupKeyboard("Internal Keyboard");
@@ -1555,6 +1628,7 @@
   // Remap Caps Lock to Control.
   IntegerPrefMember caps_lock;
   InitModifierKeyPref(&caps_lock, ::prefs::kLanguageRemapCapsLockKeyTo,
+                      ui::mojom::ModifierKey::kCapsLock,
                       ui::mojom::ModifierKey::kControl);
 
   // Press Caps Lock. CapsLock is enabled but we have remapped the key to
@@ -1612,6 +1686,7 @@
   // Remap CapsLock to Search.
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapCapsLockKeyTo,
+                      ui::mojom::ModifierKey::kCapsLock,
                       ui::mojom::ModifierKey::kMeta);
 
   // Now that CapsLock is enabled, press the remapped CapsLock button again
@@ -1638,6 +1713,7 @@
   // Remap CapsLock key back to CapsLock.
   IntegerPrefMember capslock;
   InitModifierKeyPref(&capslock, ::prefs::kLanguageRemapCapsLockKeyTo,
+                      ui::mojom::ModifierKey::kCapsLock,
                       ui::mojom::ModifierKey::kCapsLock);
 
   // Now press CapsLock again and now expect that the CapsLock modifier is
@@ -1668,6 +1744,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapCapsLockKeyTo,
+                      ui::mojom::ModifierKey::kCapsLock,
                       ui::mojom::ModifierKey::kControl);
 
   TestExternalGenericKeyboard({
@@ -1702,6 +1779,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapCapsLockKeyTo,
+                      ui::mojom::ModifierKey::kCapsLock,
                       ui::mojom::ModifierKey::kControl);
 
   SetupKeyboard("External Generic Keyboard", kKbdTopRowLayoutUnspecified,
@@ -2715,6 +2793,7 @@
        TestRewriteFunctionKeysCustomLayoutsActionSuppressedUnchanged) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   // An action key on these devices is one where the scan code matches an entry
   // in the layout map. With Meta + Top Row Key rewrites being suppressed, the
@@ -2745,10 +2824,12 @@
        TestRewriteFunctionKeysCustomLayoutsActionSuppressedWithTopRowAreFKeys) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   BooleanPrefMember send_function_keys_pref;
   send_function_keys_pref.Init(prefs::kSendFunctionKeys, prefs());
   send_function_keys_pref.SetValue(true);
+  keyboard_settings->top_row_are_fkeys = true;
 
   // An action key on these devices is one where the scan code matches an entry
   // in the layout map. With Meta + Top Row Key rewrites being suppressed, the
@@ -3039,6 +3120,7 @@
        TestFunctionKeysLayout2SuppressMetaTopRowKeyRewrites) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   // With Meta + Top Row Key rewrites suppressed, F-Keys should be translated to
   // the equivalent action key and not lose the Search modifier.
@@ -3111,12 +3193,14 @@
     TestFunctionKeysLayout2SuppressMetaTopRowKeyRewritesWithTreatTopRowAsFKeys) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   // Enable preference treat-top-row-as-function-keys.
   // That causes action keys to be mapped back to Fn keys.
   BooleanPrefMember top_row_as_fn_key;
   top_row_as_fn_key.Init(prefs::kSendFunctionKeys, prefs());
   top_row_as_fn_key.SetValue(true);
+  keyboard_settings->top_row_are_fkeys = true;
 
   // With Meta + Top Row Key rewrites suppressed and TopRowAsFKeys enabled,
   // F-Keys should not be translated and search modifier should be kept.
@@ -3712,6 +3796,7 @@
        TestRewriteActionKeysWilcoLayoutsSuppressMetaTopRowKeyRewrites) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   // With |SuppressMetaTopRowKeyComboRewrites|, all action keys should be
   // unchanged and keep the search modifier.
@@ -3848,12 +3933,14 @@
     TestRewriteActionKeysWilcoLayoutsSuppressMetaTopRowKeyRewritesWithTopRowAreFkeys) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
   delegate_->SuppressMetaTopRowKeyComboRewrites(true);
+  keyboard_settings->suppress_meta_fkey_rewrites = true;
 
   // Enable preference treat-top-row-as-function-keys.
   // That causes action keys to be mapped back to Fn keys.
   BooleanPrefMember top_row_as_fn_key;
   top_row_as_fn_key.Init(prefs::kSendFunctionKeys, prefs());
   top_row_as_fn_key.SetValue(true);
+  keyboard_settings->top_row_are_fkeys = true;
 
   // With |SuppressMetaTopRowKeyComboRewrites| and TopRowAreFKeys, all action
   // keys should be remapped to F-Keys and keep the Search modifier.
@@ -3973,6 +4060,7 @@
   BooleanPrefMember top_row_as_fn_key;
   top_row_as_fn_key.Init(prefs::kSendFunctionKeys, prefs());
   top_row_as_fn_key.SetValue(true);
+  keyboard_settings->top_row_are_fkeys = true;
 
   KeyTestCase wilco_standard_tests[] = {
       // Back -> F1, Search + Back -> Back
@@ -4222,6 +4310,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember search;
   InitModifierKeyPref(&search, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kMeta);
 
   TestChromeKeyboardVariants({
@@ -4244,6 +4333,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kAlt);
 
   SetupKeyboard("Internal Keyboard");
@@ -4270,6 +4360,7 @@
   Preferences::RegisterProfilePrefs(prefs()->registry());
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kAlt);
 
   SetupKeyboard("Internal Keyboard");
@@ -4375,9 +4466,23 @@
 
   void InitModifierKeyPref(IntegerPrefMember* int_pref,
                            const std::string& pref_name,
-                           ui::mojom::ModifierKey modifierKey) {
-    int_pref->Init(pref_name, prefs());
-    int_pref->SetValue(static_cast<int>(modifierKey));
+                           ui::mojom::ModifierKey remap_from,
+                           ui::mojom::ModifierKey remap_to) {
+    if (!features::IsInputDeviceSettingsSplitEnabled()) {
+      if (int_pref->GetPrefName() !=
+          pref_name) {  // skip if already initialized.
+        int_pref->Init(pref_name, prefs());
+      }
+      int_pref->SetValue(static_cast<int>(remap_to));
+      return;
+    }
+
+    if (remap_from == remap_to) {
+      keyboard_settings->modifier_remappings.erase(remap_from);
+      return;
+    }
+
+    keyboard_settings->modifier_remappings[remap_from] = remap_to;
   }
 
   void PopEvents(std::vector<std::unique_ptr<ui::Event>>* events) {
@@ -4386,6 +4491,15 @@
 
   void SetUp() override {
     ChromeAshTestBase::SetUp();
+    input_device_settings_controller_resetter_ = std::make_unique<
+        InputDeviceSettingsController::ScopedResetterForTest>();
+    input_device_settings_controller_mock_ =
+        std::make_unique<MockInputDeviceSettingsController>();
+    keyboard_settings = mojom::KeyboardSettings::New();
+    EXPECT_CALL(*input_device_settings_controller_mock_,
+                GetKeyboardSettings(testing::_))
+        .WillRepeatedly(testing::Return(keyboard_settings.get()));
+
     sticky_keys_controller_ = Shell::Get()->sticky_keys_controller();
     delegate_ = std::make_unique<EventRewriterDelegateImpl>(nullptr);
     delegate_->set_pref_service_for_testing(prefs());
@@ -4398,18 +4512,25 @@
   }
 
   void TearDown() override {
+    input_device_settings_controller_mock_.reset();
+    input_device_settings_controller_resetter_.reset();
     rewriter_.reset();
     ChromeAshTestBase::TearDown();
   }
 
  protected:
   raw_ptr<StickyKeysController, ExperimentalAsh> sticky_keys_controller_;
+  std::unique_ptr<MockInputDeviceSettingsController>
+      input_device_settings_controller_mock_;
+  mojom::KeyboardSettingsPtr keyboard_settings;
 
  private:
   std::unique_ptr<EventRewriterDelegateImpl> delegate_;
   std::unique_ptr<ui::KeyboardCapability> keyboard_capability_;
   input_method::FakeImeKeyboard fake_ime_keyboard_;
   std::unique_ptr<ui::EventRewriterAsh> rewriter_;
+  std::unique_ptr<InputDeviceSettingsController::ScopedResetterForTest>
+      input_device_settings_controller_resetter_;
 
   EventBuffer buffer_;
   TestEventSource source_;
@@ -4434,6 +4555,7 @@
   BooleanPrefMember send_function_keys_pref;
   send_function_keys_pref.Init(prefs::kSendFunctionKeys, prefs());
   send_function_keys_pref.SetValue(true);
+  keyboard_settings->top_row_are_fkeys = true;
   ui::EventDispatchDetails details = Send(&press_f1);
   ASSERT_FALSE(details.dispatcher_destroyed);
   PopEvents(&events);
@@ -4446,6 +4568,7 @@
   // If the pref isn't set when an event is sent to a regular window, F1 is
   // rewritten to the back key.
   send_function_keys_pref.SetValue(false);
+  keyboard_settings->top_row_are_fkeys = false;
   details = Send(&press_f1);
   ASSERT_FALSE(details.dispatcher_destroyed);
   PopEvents(&events);
@@ -4869,6 +4992,7 @@
   // Remap Control to Alt.
   IntegerPrefMember control;
   InitModifierKeyPref(&control, ::prefs::kLanguageRemapControlKeyTo,
+                      ui::mojom::ModifierKey::kControl,
                       ui::mojom::ModifierKey::kAlt);
 
   // Sends the same events once again and expect that it will be rewritten to
@@ -5359,6 +5483,8 @@
                      std::vector<std::string>>> {
  public:
   void SetUp() override {
+    scoped_feature_list_.InitAndDisableFeature(
+        features::kInputDeviceSettingsSplit);
     EventRewriterTest::SetUp();
     std::tie(event_, modifier_key_usage_mapping_, key_pref_names_) = GetParam();
   }
@@ -5482,6 +5608,7 @@
   for (const auto& pref_name : key_pref_names_) {
     IntegerPrefMember pref_member;
     InitModifierKeyPref(&pref_member, pref_name,
+                        ui::mojom::ModifierKey::kControl,
                         ui::mojom::ModifierKey::kBackspace);
   }
 
@@ -5541,6 +5668,7 @@
   for (const auto& pref_name : key_pref_names_) {
     IntegerPrefMember pref_member;
     InitModifierKeyPref(&pref_member, pref_name,
+                        ui::mojom::ModifierKey::kControl,
                         ui::mojom::ModifierKey::kControl);
   }
 
diff --git a/chrome/browser/ash/login/active_directory_migration_utils.cc b/chrome/browser/ash/login/active_directory_migration_utils.cc
deleted file mode 100644
index bc135cd..0000000
--- a/chrome/browser/ash/login/active_directory_migration_utils.cc
+++ /dev/null
@@ -1,48 +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 "chrome/browser/ash/login/active_directory_migration_utils.h"
-
-#include "ash/constants/ash_paths.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/functional/callback.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/task/task_traits.h"
-#include "base/task/thread_pool.h"
-
-namespace ash {
-namespace ad_migration_utils {
-
-namespace {
-
-constexpr char kChromadMigrationSkipOobePreservePath[] =
-    "preserve/chromad_migration_skip_oobe";
-
-}  // namespace
-
-void CheckChromadMigrationOobeFlow(base::OnceCallback<void(bool)> callback) {
-  base::FilePath preinstalled_components_dir;
-
-  if (base::PathService::Get(DIR_PREINSTALLED_COMPONENTS,
-                             &preinstalled_components_dir)) {
-    base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE,
-        {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-        base::BindOnce(&base::PathExists,
-                       preinstalled_components_dir.AppendASCII(
-                           kChromadMigrationSkipOobePreservePath)),
-        std::move(callback));
-  } else {
-    LOG(WARNING) << "Failed to get the path to the preinstalled components. "
-                    "The Welcome Screen won't be skipped in case this is part "
-                    "of the Chromad migration flow.";
-  }
-}
-
-}  // namespace ad_migration_utils
-}  // namespace ash
diff --git a/chrome/browser/ash/login/active_directory_migration_utils.h b/chrome/browser/ash/login/active_directory_migration_utils.h
deleted file mode 100644
index d9c7ad7..0000000
--- a/chrome/browser/ash/login/active_directory_migration_utils.h
+++ /dev/null
@@ -1,23 +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 CHROME_BROWSER_ASH_LOGIN_ACTIVE_DIRECTORY_MIGRATION_UTILS_H_
-#define CHROME_BROWSER_ASH_LOGIN_ACTIVE_DIRECTORY_MIGRATION_UTILS_H_
-
-#include "base/functional/callback.h"
-
-namespace ash {
-
-// Utils that provides functionalities related to skipping some OOBE screens
-// during the migration of Chromad devices into cloud management.
-// TODO(crbug/1298038): Remove this file and it's usage when Chromad to clould
-// migration is complete.
-namespace ad_migration_utils {
-
-void CheckChromadMigrationOobeFlow(base::OnceCallback<void(bool)> callback);
-
-}  // namespace ad_migration_utils
-}  // namespace ash
-
-#endif  // CHROME_BROWSER_ASH_LOGIN_ACTIVE_DIRECTORY_MIGRATION_UTILS_H_
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
index 17a0863d..d8ad368 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -20,7 +20,6 @@
 #include "base/system/sys_info.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/timer/elapsed_timer.h"
-#include "chrome/browser/ash/login/active_directory_migration_utils.h"
 #include "chrome/browser/ash/login/configuration_keys.h"
 #include "chrome/browser/ash/login/enrollment/enrollment_uma.h"
 #include "chrome/browser/ash/login/screen_manager.h"
@@ -153,10 +152,6 @@
   retry_policy_.always_use_initial_delay = true;
   retry_backoff_ = std::make_unique<net::BackoffEntry>(&retry_policy_);
 
-  ad_migration_utils::CheckChromadMigrationOobeFlow(
-      base::BindOnce(&EnrollmentScreen::UpdateChromadMigrationOobeFlow,
-                     weak_ptr_factory_.GetWeakPtr()));
-
   network_state_informer_ = base::MakeRefCounted<NetworkStateInformer>();
   network_state_informer_->Init();
 }
@@ -807,13 +802,8 @@
   BaseScreen::OnUserAction(args);
 }
 
-void EnrollmentScreen::UpdateChromadMigrationOobeFlow(bool exists) {
-  is_chromad_migration_oobe_flow_ = exists;
-}
-
 bool EnrollmentScreen::IsAutomaticEnrollmentFlow() {
-  return is_chromad_migration_oobe_flow_ ||
-         WizardController::IsZeroTouchHandsOffOobeFlow() || is_rollback_flow_;
+  return WizardController::IsZeroTouchHandsOffOobeFlow() || is_rollback_flow_;
 }
 
 bool EnrollmentScreen::IsEnrollmentScreenHiddenByError() {
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.h b/chrome/browser/ash/login/enrollment/enrollment_screen.h
index a73ac70..0814a080 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_screen.h
+++ b/chrome/browser/ash/login/enrollment/enrollment_screen.h
@@ -225,10 +225,6 @@
   // to reboot the device.
   void CheckInstallAttributesState();
 
-  // Updates the local variable, according to the existence of the Chromad
-  // migration flag file.
-  void UpdateChromadMigrationOobeFlow(bool exists);
-
   // Indicates whether this is an automatic enrollment as part of Zero-Touch
   // Hands Off flow or Chromad Migration.
   bool IsAutomaticEnrollmentFlow();
@@ -266,11 +262,6 @@
   // Timer for install attribute to resolve.
   base::OneShotTimer wait_state_timer_;
 
-  // This local flag should be true if the OOBE flow is operating as part of the
-  // Chromad to cloud device migration. If so, "Enterprise enrollment complete"
-  // screen should be skipped.
-  bool is_chromad_migration_oobe_flow_ = false;
-
   // Whether the ongoing flow belongs to an enterprise rollback.
   bool is_rollback_flow_ = false;
 
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc
index 3cb08fd..425c4a9 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc
@@ -744,45 +744,6 @@
   EXPECT_TRUE(StartupUtils::IsDeviceRegistered());
 }
 
-class EnrollmentScreenChromadMigrationTest : public EnrollmentScreenTest {
- public:
-  EnrollmentScreenChromadMigrationTest() = default;
-  ~EnrollmentScreenChromadMigrationTest() override = default;
-
-  EnrollmentScreenChromadMigrationTest(
-      const EnrollmentScreenChromadMigrationTest&) = delete;
-  EnrollmentScreenChromadMigrationTest& operator=(
-      const EnrollmentScreenChromadMigrationTest&) = delete;
-
-  // EnrollmentScreenTest:
-  bool SetUpUserDataDirectory() override {
-    if (!EnrollmentScreenTest::SetUpUserDataDirectory())
-      return false;
-
-    base::FilePath preinstalled_components_dir;
-    EXPECT_TRUE(base::PathService::Get(DIR_PREINSTALLED_COMPONENTS,
-                                       &preinstalled_components_dir));
-
-    base::FilePath preserve_dir =
-        preinstalled_components_dir.AppendASCII("preserve/");
-    EXPECT_TRUE(base::CreateDirectory(preserve_dir));
-    EXPECT_TRUE(base::WriteFile(
-        preserve_dir.AppendASCII("chromad_migration_skip_oobe"), "1"));
-
-    return true;
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(EnrollmentScreenChromadMigrationTest,
-                       SkipEnrollmentCompleteScreen) {
-  enrollment_ui_.SetExitHandler();
-  enrollment_screen()->OnDeviceAttributeUpdatePermission(false /* granted */);
-  EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit();
-  EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result);
-
-  EXPECT_TRUE(StartupUtils::IsDeviceRegistered());
-}
-
 // Class to test TPM pre-enrollment check that happens only with
 // --tpm-is-dynamic switch enabled. Test parameter represents take TPM
 // ownership reply possible statuses.
diff --git a/chrome/browser/ash/login/screens/welcome_screen.cc b/chrome/browser/ash/login/screens/welcome_screen.cc
index 9930465..b9121fd 100644
--- a/chrome/browser/ash/login/screens/welcome_screen.cc
+++ b/chrome/browser/ash/login/screens/welcome_screen.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/ash/accessibility/magnification_manager.h"
 #include "chrome/browser/ash/base/locale_util.h"
 #include "chrome/browser/ash/customization/customization_document.h"
-#include "chrome/browser/ash/login/active_directory_migration_utils.h"
 #include "chrome/browser/ash/login/configuration_keys.h"
 #include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h"
 #include "chrome/browser/ash/login/login_pref_names.h"
@@ -195,9 +194,6 @@
       exit_callback_(exit_callback) {
   input_method::InputMethodManager::Get()->AddObserver(this);
 
-  ad_migration_utils::CheckChromadMigrationOobeFlow(
-      base::BindOnce(&WelcomeScreen::UpdateChromadMigrationOobeFlow,
-                     weak_ptr_factory_.GetWeakPtr()));
   AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
   CHECK(accessibility_manager);
   accessibility_subscription_ = accessibility_manager->RegisterCallback(
@@ -366,11 +362,10 @@
   }
 
   // Skip this screen if this is an automatic enrollment as part of Zero-Touch
-  // hands off flow or Chromad Migration flow.
+  // hands off flow.
   // TODO(crbug.com/1295708): Move this check to an implementation of
   // BaseScreen:MaybeSkip().
-  if (is_chromad_migration_oobe_flow_ ||
-      WizardController::IsZeroTouchHandsOffOobeFlow()) {
+  if (WizardController::IsZeroTouchHandsOffOobeFlow()) {
     OnContinueButtonPressed();
     return;
   }
@@ -682,17 +677,6 @@
   return chromevox_hint_detector_.get();
 }
 
-void WelcomeScreen::UpdateChromadMigrationOobeFlow(bool exists) {
-  is_chromad_migration_oobe_flow_ = exists;
-
-  if (is_hidden() || !is_chromad_migration_oobe_flow_)
-    return;
-
-  // Simulates a user action, in case this screen is already shown and this OOBE
-  // flow is part of Chromad to cloud migration.
-  OnContinueButtonPressed();
-}
-
 void WelcomeScreen::OnAccessibilityStatusChanged(
     const AccessibilityStatusEventDetails& details) {
   if (details.notification_type ==
diff --git a/chrome/browser/ash/login/screens/welcome_screen.h b/chrome/browser/ash/login/screens/welcome_screen.h
index b2872891..492c715 100644
--- a/chrome/browser/ash/login/screens/welcome_screen.h
+++ b/chrome/browser/ash/login/screens/welcome_screen.h
@@ -175,11 +175,6 @@
   void NotifyLocaleChange();
   void OnLocaleChangeResult(LocaleNotificationResult result);
 
-  // Updates the local variable according to the existence of the Chromad
-  // migration flag file. Then, simulates a user action, if the flag is set and
-  // the screen is not hidden.
-  void UpdateChromadMigrationOobeFlow(bool exists);
-
   void OnAccessibilityStatusChanged(
       const AccessibilityStatusEventDetails& details);
   void UpdateA11yState();
@@ -201,10 +196,6 @@
 
   base::ObserverList<Observer>::Unchecked observers_;
 
-  // This local flag should be true if the OOBE flow is operating as part of the
-  // Chromad to cloud device migration. If so, this screen should be skipped.
-  bool is_chromad_migration_oobe_flow_ = false;
-
   base::CallbackListSubscription accessibility_subscription_;
 
   base::WeakPtr<quick_start::TargetDeviceBootstrapController>
diff --git a/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc b/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
index b55cb0e4..1edd2c66 100644
--- a/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
@@ -545,35 +545,6 @@
   WaitForScreenExit();
 }
 
-class WelcomeScreenChromadMigrationBrowserTest
-    : public WelcomeScreenBrowserTest {
- public:
-  WelcomeScreenChromadMigrationBrowserTest() = default;
-  ~WelcomeScreenChromadMigrationBrowserTest() override = default;
-
-  // WelcomeScreenBrowserTest:
-  bool SetUpUserDataDirectory() override {
-    if (!WelcomeScreenBrowserTest::SetUpUserDataDirectory())
-      return false;
-
-    base::FilePath preinstalled_components_dir;
-    EXPECT_TRUE(base::PathService::Get(DIR_PREINSTALLED_COMPONENTS,
-                                       &preinstalled_components_dir));
-
-    base::FilePath preserve_dir =
-        preinstalled_components_dir.AppendASCII("preserve/");
-    EXPECT_TRUE(base::CreateDirectory(preserve_dir));
-    EXPECT_TRUE(base::WriteFile(
-        preserve_dir.AppendASCII("chromad_migration_skip_oobe"), "1"));
-
-    return true;
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(WelcomeScreenChromadMigrationBrowserTest, SkipScreen) {
-  WaitForScreenExit();
-}
-
 class WelcomeScreenTimezone : public WelcomeScreenBrowserTest {
  public:
   WelcomeScreenTimezone() {
diff --git a/chrome/browser/ash/net/apn_migrator.cc b/chrome/browser/ash/net/apn_migrator.cc
index 1bfc7d13..b9891fb5 100644
--- a/chrome/browser/ash/net/apn_migrator.cc
+++ b/chrome/browser/ash/net/apn_migrator.cc
@@ -34,17 +34,28 @@
                  << guid << ": [" << error_name << ']';
 }
 
-absl::optional<ApnPropertiesPtr> GetApnFromDict(
+absl::optional<ApnPropertiesPtr> GetPreRevampApnFromDict(
     const base::Value::Dict* cellular_dict,
-    const char* key,
-    bool is_apn_revamp_enabled) {
+    const char* key) {
   const base::Value::Dict* apn_dict =
       chromeos::network_config::GetDictionary(cellular_dict, key);
-  if (!apn_dict || !apn_dict->Find(::onc::cellular_apn::kAccessPointName)) {
+  if (!apn_dict) {
     return absl::nullopt;
   }
-  return chromeos::network_config::GetApnProperties(*apn_dict,
-                                                    is_apn_revamp_enabled);
+
+  // Pre-revamp APNs with empty kAccessPointName will be ignored as they
+  // indicate shill tried to send a NULL APN to modemmanager. If shill
+  // uses a custom APN or modem DB APN, the kAccessPointName will be
+  // non-empty.
+  const std::string* access_point_name =
+      apn_dict->FindString(::onc::cellular_apn::kAccessPointName);
+  if (!access_point_name || access_point_name->empty()) {
+    return absl::nullopt;
+  }
+
+  return chromeos::network_config::GetApnProperties(
+      *apn_dict,
+      /*is_apn_revamp_enabled=*/false);
 }
 
 bool ContainsMatchingApn(const base::Value::Dict* cellular_dict,
@@ -266,19 +277,17 @@
       SetShillCustomApnListForNetwork(*network, &empty_apn_list);
     }
   } else {
-    absl::optional<ApnPropertiesPtr> last_connected_attach_apn = GetApnFromDict(
-        cellular_dict, ::onc::cellular::kLastConnectedAttachApnProperty,
-        /*is_apn_revamp_enabled=*/false);
+    absl::optional<ApnPropertiesPtr> last_connected_attach_apn =
+        GetPreRevampApnFromDict(
+            cellular_dict, ::onc::cellular::kLastConnectedAttachApnProperty);
 
     absl::optional<ApnPropertiesPtr> last_connected_default_apn =
-        GetApnFromDict(cellular_dict,
-                       ::onc::cellular::kLastConnectedDefaultApnProperty,
-                       /*is_apn_revamp_enabled=*/false);
+        GetPreRevampApnFromDict(
+            cellular_dict, ::onc::cellular::kLastConnectedDefaultApnProperty);
 
     if (!last_connected_attach_apn && !last_connected_default_apn) {
       absl::optional<ApnPropertiesPtr> last_good_apn =
-          GetApnFromDict(cellular_dict, ::onc::cellular::kLastGoodAPN,
-                         /*is_apn_revamp_enabled=*/false);
+          GetPreRevampApnFromDict(cellular_dict, ::onc::cellular::kLastGoodAPN);
 
       if (last_good_apn && pre_revamp_custom_apn->access_point_name ==
                                (*last_good_apn)->access_point_name) {
diff --git a/chrome/browser/ash/net/apn_migrator_unittest.cc b/chrome/browser/ash/net/apn_migrator_unittest.cc
index c4289ec..65941d5 100644
--- a/chrome/browser/ash/net/apn_migrator_unittest.cc
+++ b/chrome/browser/ash/net/apn_migrator_unittest.cc
@@ -1104,6 +1104,86 @@
 
 TEST_F(
     ApnMigratorTest,
+    MigrateNonManagedNetwork_EmptyLastConnectedAttachApn_MatchingLastConnectedDefaultApn) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(features::kApnRevamp);
+
+  const std::string cellular_service_path_1 = AddTestCellularDeviceAndService(
+      kCellularName1, kTestCellularPath1, kTestCellularIccid1,
+      kTestCellularGuid1, /*is_managed=*/false);
+
+  // We will use this delegate to simulate a late async reply
+  network_handler::PropertiesCallback get_managed_properties_callback;
+
+  // Start the migration process for |cellular_service_path_1|. This will
+  // trigger a GetManagedProperties call.
+  EXPECT_CALL(*managed_cellular_pref_handler(),
+              ContainsApnMigratedIccid(Eq(kTestCellularIccid1)))
+      .WillRepeatedly(Return(false));
+  const std::string access_point_name = "apn_1";
+  base::Value::Dict custom_apn;
+  custom_apn.Set(::onc::cellular_apn::kAccessPointName, access_point_name);
+  base::Value::List populated_apn_list;
+  populated_apn_list.Append(std::move(custom_apn));
+  EXPECT_CALL(*network_metadata_store(),
+              GetPreRevampCustomApnList(kTestCellularGuid1))
+      .Times(2)
+      .WillRepeatedly(Return(&populated_apn_list));
+  EXPECT_CALL(*managed_network_configuration_handler(),
+              GetManagedProperties(LoginState::Get()->primary_user_hash(),
+                                   cellular_service_path_1, _))
+      .Times(1)
+      .WillOnce(
+          WithArg<2>(Invoke([&](network_handler::PropertiesCallback callback) {
+            ASSERT_TRUE(get_managed_properties_callback.is_null());
+            get_managed_properties_callback = std::move(callback);
+            ASSERT_FALSE(get_managed_properties_callback.is_null());
+          })));
+  // Function under test.
+  TriggerNetworkListChanged();
+
+  // Execute the GetManagedProperties callback with no last connected attach
+  // APN, and a last connected default APN that matches the persisted APN.
+  // This should trigger a call to CreateCustomApns() with the APN in the
+  // enabled state with APN types of kDefault.
+  EXPECT_CALL(*managed_network_configuration_handler(),
+              SetProperties(cellular_service_path_1, _, _, _))
+      .Times(0);
+  EXPECT_CALL(*managed_cellular_pref_handler(),
+              AddApnMigratedIccid(Eq(kTestCellularIccid1)))
+      .Times(1);
+  EXPECT_TRUE(GetCustomApns().empty());
+
+  absl::optional<base::Value::Dict> properties = base::Value::Dict();
+
+  base::Value::Dict last_connected_default_apn_dict;
+  last_connected_default_apn_dict.Set(::onc::cellular_apn::kAccessPointName,
+                                      access_point_name);
+
+  base::Value::Dict last_connected_attach_apn_dict;
+  last_connected_attach_apn_dict.Set(::onc::cellular_apn::kAccessPointName,
+                                     std::string());
+  base::Value::Dict cellular;
+  cellular.Set(::onc::cellular::kLastConnectedDefaultApnProperty,
+               std::move(last_connected_default_apn_dict));
+  cellular.Set(::onc::cellular::kLastConnectedAttachApnProperty,
+               std::move(last_connected_attach_apn_dict));
+
+  properties->Set(::onc::network_config::kCellular, std::move(cellular));
+  std::move(get_managed_properties_callback)
+      .Run(cellular_service_path_1, std::move(properties),
+           /*error=*/absl::nullopt);
+  base::RunLoop().RunUntilIdle();
+  const std::vector<ApnPropertiesPtr>& custom_apns = GetCustomApns();
+  ASSERT_EQ(1u, custom_apns.size());
+  EXPECT_EQ(access_point_name, custom_apns[0]->access_point_name);
+  EXPECT_EQ(ApnState::kEnabled, custom_apns[0]->state);
+  EXPECT_FALSE(base::Contains(custom_apns[0]->apn_types, ApnType::kAttach));
+  EXPECT_TRUE(base::Contains(custom_apns[0]->apn_types, ApnType::kDefault));
+}
+
+TEST_F(
+    ApnMigratorTest,
     MigrateNonManagedNetwork_MatchingLastConnectedAttachApnButNotDefaultApn_DefaultApnPresent) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(features::kApnRevamp);
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.cc
index 0ac1465..fc10cbe 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.cc
@@ -36,4 +36,9 @@
                                     const base::Value::List** out_value) const {
   return ::ash::CrosSettings::Get()->GetList(path, out_value);
 }
+
+bool CrosReportingSettings::GetReportingEnabled(const std::string& path,
+                                                bool* out_value) const {
+  return GetBoolean(path, out_value);
+}
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.h b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.h
index f936bf6..1581d2b 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings.h
@@ -32,6 +32,10 @@
   bool GetInteger(const std::string& path, int* out_value) const override;
   bool GetList(const std::string& path,
                const base::Value::List** out_value) const override;
+
+  // Only bool is allowed, otherwise will return false.
+  bool GetReportingEnabled(const std::string& path,
+                           bool* out_value) const override;
 };
 }  // namespace reporting
 
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings_unittest.cc
index b2dc5fb..db69155 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/cros_reporting_settings_unittest.cc
@@ -83,6 +83,33 @@
   EXPECT_THAT(list_value->front().GetString(), Eq(kListSettingValue));
 }
 
+TEST(CrosReportingSettingsTest, GetReportingEnabled) {
+  ash::ScopedTestingCrosSettings scoped_testing_cros_settings;
+  CrosReportingSettings cros_reporting_settings;
+  bool enabled_value;
+
+  scoped_testing_cros_settings.device_settings()->SetBoolean(
+      ash::kReportDeviceNetworkStatus, true);
+  bool is_valid = cros_reporting_settings.GetReportingEnabled(
+      ash::kReportDeviceNetworkStatus, &enabled_value);
+
+  ASSERT_TRUE(is_valid);
+  EXPECT_TRUE(enabled_value);
+}
+
+TEST(CrosReportingSettingsTest, GetReportingEnabled_InvalidType) {
+  ash::ScopedTestingCrosSettings scoped_testing_cros_settings;
+  CrosReportingSettings cros_reporting_settings;
+  bool enabled_value;
+
+  scoped_testing_cros_settings.device_settings()->SetInteger(
+      ash::kReportUploadFrequency, 100);
+  bool is_valid = cros_reporting_settings.GetReportingEnabled(
+      ash::kReportUploadFrequency, &enabled_value);
+
+  ASSERT_FALSE(is_valid);
+}
+
 TEST(CrosReportingSettingsTest, AddSettingsObserver) {
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings;
   CrosReportingSettings cros_reporting_settings;
diff --git a/chrome/browser/ash/printing/cups_print_job_manager.h b/chrome/browser/ash/printing/cups_print_job_manager.h
index f3748b93..ca45d4c 100644
--- a/chrome/browser/ash/printing/cups_print_job_manager.h
+++ b/chrome/browser/ash/printing/cups_print_job_manager.h
@@ -70,7 +70,7 @@
   virtual bool CreatePrintJob(
       const std::string& printer_id,
       const std::string& title,
-      int job_id,
+      uint32_t job_id,
       int total_page_number,
       ::printing::PrintJob::Source source,
       const std::string& source_id,
diff --git a/chrome/browser/ash/printing/cups_print_job_manager_impl.cc b/chrome/browser/ash/printing/cups_print_job_manager_impl.cc
index 756b11c..4c7f4cf9 100644
--- a/chrome/browser/ash/printing/cups_print_job_manager_impl.cc
+++ b/chrome/browser/ash/printing/cups_print_job_manager_impl.cc
@@ -167,7 +167,7 @@
   // |title| with the pages |total_page_number|.
   bool CreatePrintJob(const std::string& printer_id,
                       const std::string& title,
-                      int job_id,
+                      uint32_t job_id,
                       int total_page_number,
                       ::printing::PrintJob::Source source,
                       const std::string& source_id,
diff --git a/chrome/browser/ash/printing/fake_cups_print_job_manager.cc b/chrome/browser/ash/printing/fake_cups_print_job_manager.cc
index 36417c4..285090d 100644
--- a/chrome/browser/ash/printing/fake_cups_print_job_manager.cc
+++ b/chrome/browser/ash/printing/fake_cups_print_job_manager.cc
@@ -25,7 +25,7 @@
 bool FakeCupsPrintJobManager::CreatePrintJob(
     const std::string& printer_id,
     const std::string& title,
-    int job_id,
+    uint32_t job_id,
     int total_page_number,
     ::printing::PrintJob::Source source,
     const std::string& source_id,
diff --git a/chrome/browser/ash/printing/fake_cups_print_job_manager.h b/chrome/browser/ash/printing/fake_cups_print_job_manager.h
index 5939250..f8865bb 100644
--- a/chrome/browser/ash/printing/fake_cups_print_job_manager.h
+++ b/chrome/browser/ash/printing/fake_cups_print_job_manager.h
@@ -25,7 +25,7 @@
 
   bool CreatePrintJob(const std::string& printer_id,
                       const std::string& title,
-                      int job_id,
+                      uint32_t job_id,
                       int total_page_number,
                       ::printing::PrintJob::Source source,
                       const std::string& source_id,
diff --git a/chrome/browser/ash/printing/test_cups_print_job_manager.cc b/chrome/browser/ash/printing/test_cups_print_job_manager.cc
index 19152ba..effe403 100644
--- a/chrome/browser/ash/printing/test_cups_print_job_manager.cc
+++ b/chrome/browser/ash/printing/test_cups_print_job_manager.cc
@@ -33,7 +33,7 @@
 bool TestCupsPrintJobManager::CreatePrintJob(
     const std::string& printer_id,
     const std::string& title,
-    int job_id,
+    uint32_t job_id,
     int total_page_number,
     ::printing::PrintJob::Source source,
     const std::string& source_id,
diff --git a/chrome/browser/ash/printing/test_cups_print_job_manager.h b/chrome/browser/ash/printing/test_cups_print_job_manager.h
index 97fc3d5..c016b4d 100644
--- a/chrome/browser/ash/printing/test_cups_print_job_manager.h
+++ b/chrome/browser/ash/printing/test_cups_print_job_manager.h
@@ -21,7 +21,7 @@
   // CupsPrintJobManager:
   bool CreatePrintJob(const std::string& printer_id,
                       const std::string& title,
-                      int job_id,
+                      uint32_t job_id,
                       int total_page_number,
                       ::printing::PrintJob::Source source,
                       const std::string& source_id,
diff --git a/chrome/browser/ash/scanning/chrome_scanning_app_delegate.cc b/chrome/browser/ash/scanning/chrome_scanning_app_delegate.cc
index 475c2cac..86ae704 100644
--- a/chrome/browser/ash/scanning/chrome_scanning_app_delegate.cc
+++ b/chrome/browser/ash/scanning/chrome_scanning_app_delegate.cc
@@ -22,6 +22,8 @@
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/scanning/scan_service.h"
+#include "chrome/browser/ash/scanning/scan_service_factory.h"
 #include "chrome/browser/ash/scanning/scanning_file_path_helper.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
@@ -127,6 +129,21 @@
                      std::move(callback)));
 }
 
+ChromeScanningAppDelegate::BindScanServiceCallback
+ChromeScanningAppDelegate::GetBindScanServiceCallback(content::WebUI* web_ui) {
+  return base::BindRepeating(
+      [](Profile* profile,
+         mojo::PendingReceiver<ash::scanning::mojom::ScanService>
+             pending_receiver) {
+        ash::ScanService* service =
+            ash::ScanServiceFactory::GetForBrowserContext(profile);
+        if (service) {
+          service->BindInterface(std::move(pending_receiver));
+        }
+      },
+      Profile::FromWebUI(web_ui));
+}
+
 void ChromeScanningAppDelegate::OnPathExists(
     const base::FilePath& path_to_file,
     base::OnceCallback<void(bool)> callback,
diff --git a/chrome/browser/ash/scanning/chrome_scanning_app_delegate.h b/chrome/browser/ash/scanning/chrome_scanning_app_delegate.h
index f2ab924..f4598bb 100644
--- a/chrome/browser/ash/scanning/chrome_scanning_app_delegate.h
+++ b/chrome/browser/ash/scanning/chrome_scanning_app_delegate.h
@@ -57,6 +57,8 @@
   void SaveScanSettingsToPrefs(const std::string& scan_settings) override;
   void ShowFileInFilesApp(const base::FilePath& path_to_file,
                           base::OnceCallback<void(bool)> callback) override;
+  BindScanServiceCallback GetBindScanServiceCallback(
+      content::WebUI* web_ui) override;
 
   // Register scan settings prefs.
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.cc b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.cc
index 46e644fe..e8a5b9f 100644
--- a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.cc
+++ b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/webui/ash/diagnostics_dialog.h"
 #include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
 #include "chrome/services/qrcode_generator/public/mojom/qrcode_generator.mojom.h"
+#include "content/public/browser/web_ui.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/image/image_skia.h"
@@ -26,7 +27,7 @@
 namespace ash {
 namespace shimless_rma {
 
-ChromeShimlessRmaDelegate::ChromeShimlessRmaDelegate() = default;
+ChromeShimlessRmaDelegate::ChromeShimlessRmaDelegate(content::WebUI* web_ui) {}
 ChromeShimlessRmaDelegate::~ChromeShimlessRmaDelegate() = default;
 
 void ChromeShimlessRmaDelegate::ExitRmaThenRestartChrome() {
diff --git a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h
index e9bf623..5a475248 100644
--- a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h
+++ b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h
@@ -14,11 +14,15 @@
 #include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
 #include "chrome/services/qrcode_generator/public/mojom/qrcode_generator.mojom.h"
 
+namespace content {
+class WebUI;
+}  // namespace content
+
 namespace ash::shimless_rma {
 
 class ChromeShimlessRmaDelegate : public ShimlessRmaDelegate {
  public:
-  ChromeShimlessRmaDelegate();
+  explicit ChromeShimlessRmaDelegate(content::WebUI* web_ui);
 
   ChromeShimlessRmaDelegate(const ChromeShimlessRmaDelegate&) = delete;
   ChromeShimlessRmaDelegate& operator=(const ChromeShimlessRmaDelegate&) =
diff --git a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate_unittest.cc b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate_unittest.cc
index 2407a96..a8465f8 100644
--- a/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate_unittest.cc
+++ b/chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate_unittest.cc
@@ -32,7 +32,8 @@
 class ChromeShimlessRmaDelegateTest : public testing::Test {
  public:
   ChromeShimlessRmaDelegateTest()
-      : task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD) {}
+      : chrome_shimless_rma_delegate_(ChromeShimlessRmaDelegate(nullptr)),
+        task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD) {}
   ~ChromeShimlessRmaDelegateTest() override = default;
 
   void SetUp() override {
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc
index efb6988..6ce9e08b 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_browsertest_fixture.cc
@@ -14,9 +14,9 @@
 #include "ash/webui/personalization_app/personalization_app_url_constants.h"
 #include "ash/webui/personalization_app/test/fake_personalization_app_ambient_provider.h"
 #include "ash/webui/personalization_app/test/fake_personalization_app_keyboard_backlight_provider.h"
-#include "ash/webui/personalization_app/test/fake_personalization_app_theme_provider.h"
 #include "ash/webui/personalization_app/test/fake_personalization_app_user_provider.h"
 #include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h"
+#include "chrome/browser/ash/web_applications/personalization_app/personalization_app_theme_provider_impl.h"
 #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_utils.h"
 #include "chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h"
 #include "chrome/browser/profiles/profile.h"
@@ -36,7 +36,7 @@
   auto keyboard_backlight_provider =
       std::make_unique<FakePersonalizationAppKeyboardBacklightProvider>(web_ui);
   auto theme_provider =
-      std::make_unique<FakePersonalizationAppThemeProvider>(web_ui);
+      std::make_unique<PersonalizationAppThemeProviderImpl>(web_ui);
   auto wallpaper_provider =
       std::make_unique<PersonalizationAppWallpaperProviderImpl>(
           web_ui,
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
index eb13217..edc4e663 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -96,10 +96,6 @@
                                   : base::UnguessableToken::Create().ToString();
 }
 
-scoped_refptr<base::RefCountedMemory> GetPreviewWallpaper() {
-  return WallpaperController::Get()->GetPreviewImage();
-}
-
 std::string GetJpegDataUrl(const unsigned char* data, size_t size) {
   std::string output = "data:image/jpeg;base64,";
   base::Base64EncodeAppend(base::make_span(data, size), &output);
@@ -160,15 +156,7 @@
 
 void PersonalizationAppWallpaperProviderImpl::GetWallpaperAsJpegBytes(
     content::WebUIDataSource::GotDataCallback callback) {
-  // |GetWallpaperAsJpegBytes| is called in the hot path of switching wallpaper
-  // on the UI thread right after user makes a new selection. Make sure to do
-  // resizing and encoding on a task runner to avoid locking up the UI as the
-  // user's wallpaper is being set.
-  base::ThreadPool::PostTaskAndReplyWithResult(
-      FROM_HERE,
-      {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-      base::BindOnce(&GetPreviewWallpaper), std::move(callback));
+  WallpaperController::Get()->LoadPreviewImage(std::move(callback));
 }
 
 bool PersonalizationAppWallpaperProviderImpl::IsEligibleForGooglePhotos() {
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
index 0691aa83..408ad0cc 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -412,25 +412,20 @@
 }
 
 TEST_F(PersonalizationAppWallpaperProviderImplTest, GetWallpaperAsJpegBytes) {
-  test_wallpaper_controller()->ShowWallpaperImage(
-      CreateSolidImageSkia(/*width=*/1, /*height=*/1, SK_ColorRED));
+  auto image = CreateSolidImageSkia(/*width=*/1, /*height=*/1, SK_ColorRED);
+  test_wallpaper_controller()->ShowWallpaperImage(image);
+  scoped_refptr<base::RefCountedMemory> expected_jpeg_bytes =
+      gfx::Image(image).As1xPNGBytes();
 
-  scoped_refptr<base::RefCountedMemory> jpeg_bytes;
-
+  // Jpeg bytes of the preview image.
   base::RunLoop loop;
-  delegate()->GetWallpaperAsJpegBytes(base::BindLambdaForTesting(
-      [quit = loop.QuitClosure(),
-       &jpeg_bytes](scoped_refptr<base::RefCountedMemory> bytes) {
-        bytes.swap(jpeg_bytes);
+  test_wallpaper_controller()->LoadPreviewImage(base::BindLambdaForTesting(
+      [quit = loop.QuitClosure(), &expected_jpeg_bytes](
+          scoped_refptr<base::RefCountedMemory> preview_bytes) {
+        EXPECT_TRUE(preview_bytes->Equals(expected_jpeg_bytes));
         std::move(quit).Run();
       }));
   loop.Run();
-
-  // Jpeg bytes of the preview image.
-  scoped_refptr<base::RefCountedMemory> expected_jpeg_bytes =
-      test_wallpaper_controller()->GetPreviewImage();
-
-  EXPECT_TRUE(expected_jpeg_bytes->Equals(jpeg_bytes));
 }
 
 TEST_F(PersonalizationAppWallpaperProviderImplTest, SetDailyRefreshBanned) {
diff --git a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
index 737617e1..f40be62e 100644
--- a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
@@ -636,12 +636,12 @@
 
   ValidateBrowsingDataEntries(
       browsing_data_model.get(),
-      {{iwa_url_info1.origin().host(),
+      {{iwa_url_info1.origin(),
         iwa_url_info1.origin(),
         {static_cast<BrowsingDataModel::StorageType>(
              ChromeBrowsingDataModelDelegate::StorageType::kIsolatedWebApp),
          /*storage_size=*/105, /*cookie_count=*/0}},
-       {iwa_url_info2.origin().host(),
+       {iwa_url_info2.origin(),
         iwa_url_info2.origin(),
         {static_cast<BrowsingDataModel::StorageType>(
              ChromeBrowsingDataModelDelegate::StorageType::kIsolatedWebApp),
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.cc
index 4e4a867..1538aa6 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.cc
@@ -108,3 +108,23 @@
   // typesdeletion methods that require a callback.
   std::move(callback).Run();
 }
+
+absl::optional<BrowsingDataModel::DataOwner>
+ChromeBrowsingDataModelDelegate::GetDataOwner(
+    BrowsingDataModel::DataKey data_key,
+    BrowsingDataModel::StorageType storage_type) const {
+  switch (static_cast<StorageType>(storage_type)) {
+    case StorageType::kIsolatedWebApp:
+      CHECK(absl::holds_alternative<url::Origin>(data_key))
+          << "Unsupported IWA DataKey type: " << data_key.index();
+      return absl::get<url::Origin>(data_key);
+
+    case StorageType::kTopics:
+      CHECK(absl::holds_alternative<url::Origin>(data_key))
+          << "Unsupported Topics DataKey type: " << data_key.index();
+      return absl::get<url::Origin>(data_key).host();
+
+    default:
+      return absl::nullopt;
+  }
+}
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h b/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h
index fd00460f..46f5b1a 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h
+++ b/chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h
@@ -46,6 +46,9 @@
   void RemoveDataKey(BrowsingDataModel::DataKey data_key,
                      BrowsingDataModel::StorageTypeSet storage_types,
                      base::OnceClosure callback) override;
+  absl::optional<BrowsingDataModel::DataOwner> GetDataOwner(
+      BrowsingDataModel::DataKey data_key,
+      BrowsingDataModel::StorageType storage_type) const override;
 
  private:
   ChromeBrowsingDataModelDelegate(Profile* profile,
diff --git a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.cc b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.cc
index 923144ad..aa63345e 100644
--- a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.cc
+++ b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.cc
@@ -129,6 +129,11 @@
   return false;
 }
 
+bool DeviceReportingSettingsLacros::GetReportingEnabled(const std::string& path,
+                                                        bool* out_value) const {
+  return GetBoolean(path, out_value);
+}
+
 bool DeviceReportingSettingsLacros::GetInteger(const std::string& policy_name,
                                                int* out_value) const {
   crosapi::mojom::DeviceSettings* const device_settings =
diff --git a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.h b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.h
index 6e7dc42..bbea585 100644
--- a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.h
+++ b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros.h
@@ -76,6 +76,9 @@
                   int* out_value) const override;
   bool GetList(const std::string& policy_name,
                const base::Value::List** out_value) const override;
+  // Only bool settings are allowed.
+  bool GetReportingEnabled(const std::string& path,
+                           bool* out_value) const override;
 
  private:
   explicit DeviceReportingSettingsLacros(std::unique_ptr<Delegate> delegate);
diff --git a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros_unittest.cc b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros_unittest.cc
index e87690b..4328745 100644
--- a/chrome/browser/chromeos/reporting/device_reporting_settings_lacros_unittest.cc
+++ b/chrome/browser/chromeos/reporting/device_reporting_settings_lacros_unittest.cc
@@ -79,6 +79,10 @@
   int int_value;
   EXPECT_FALSE(device_reporting_settings_->GetInteger(
       ::policy::key::kReportDeviceNetworkStatus, &int_value));
+
+  // Cannot get reporting enabled from an integer setting.
+  EXPECT_FALSE(device_reporting_settings_->GetReportingEnabled(
+      ::policy::key::kReportUploadFrequency, &bool_value));
 }
 
 TEST_F(DeviceReportingSettingsLacrosTest, GetBoolean) {
@@ -94,6 +98,19 @@
   EXPECT_TRUE(value);
 }
 
+TEST_F(DeviceReportingSettingsLacrosTest, GetReportingEnabled) {
+  crosapi::mojom::DeviceSettingsPtr device_settings_ptr =
+      crosapi::mojom::DeviceSettings::New();
+  device_settings_ptr->report_device_network_status =
+      crosapi::mojom::DeviceSettings::OptionalBool::kTrue;
+  delegate_->UpdateDeviceSettings(device_settings_ptr.get());
+
+  bool value = false;
+  ASSERT_TRUE(device_reporting_settings_->GetReportingEnabled(
+      ::policy::key::kReportDeviceNetworkStatus, &value));
+  EXPECT_TRUE(value);
+}
+
 TEST_F(DeviceReportingSettingsLacrosTest, GetInteger) {
   constexpr int kUploadFrequency = 100;
   crosapi::mojom::NullableInt64Ptr upload_frequency =
diff --git a/chrome/browser/chromeos/reporting/user_reporting_settings.cc b/chrome/browser/chromeos/reporting/user_reporting_settings.cc
index 6b5f37a8..0a979239 100644
--- a/chrome/browser/chromeos/reporting/user_reporting_settings.cc
+++ b/chrome/browser/chromeos/reporting/user_reporting_settings.cc
@@ -90,6 +90,22 @@
   return true;
 }
 
+bool UserReportingSettings::GetReportingEnabled(const std::string& path,
+                                                bool* out_value) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(profile_);
+
+  const base::Value::List* list_value;
+  if (GetBoolean(path, out_value)) {
+    return true;
+  } else if (GetList(path, &list_value)) {
+    *out_value = !list_value->empty();
+    return true;
+  }
+
+  return false;
+}
+
 void UserReportingSettings::OnPrefChanged(const std::string& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(settings_observers_.contains(path));
diff --git a/chrome/browser/chromeos/reporting/user_reporting_settings.h b/chrome/browser/chromeos/reporting/user_reporting_settings.h
index b4170b0..27065be 100644
--- a/chrome/browser/chromeos/reporting/user_reporting_settings.h
+++ b/chrome/browser/chromeos/reporting/user_reporting_settings.h
@@ -42,6 +42,10 @@
   bool GetList(const std::string& path,
                const base::Value::List** out_value) const override;
 
+  // Only bool and List are allowed, otherwise will return false.
+  bool GetReportingEnabled(const std::string& path,
+                           bool* out_value) const override;
+
  private:
   // Internal callback triggered when the setting value is updated.
   void OnPrefChanged(const std::string& path);
diff --git a/chrome/browser/chromeos/reporting/user_reporting_settings_unittest.cc b/chrome/browser/chromeos/reporting/user_reporting_settings_unittest.cc
index b4a6a07..b431277 100644
--- a/chrome/browser/chromeos/reporting/user_reporting_settings_unittest.cc
+++ b/chrome/browser/chromeos/reporting/user_reporting_settings_unittest.cc
@@ -50,6 +50,8 @@
   bool out_bool_value;
   ASSERT_FALSE(
       user_reporting_settings_->GetBoolean(kSettingPath, &out_bool_value));
+  ASSERT_FALSE(user_reporting_settings_->GetReportingEnabled(kSettingPath,
+                                                             &out_bool_value));
   const base::Value::List* out_list_value = nullptr;
   ASSERT_FALSE(
       user_reporting_settings_->GetList(kSettingPath, &out_list_value));
@@ -110,6 +112,20 @@
   EXPECT_TRUE(out_value);
 }
 
+TEST_F(UserReportingSettingsTest, GetReportingEnabled_Boolean) {
+  profile_->GetTestingPrefService()->registry()->RegisterBooleanPref(
+      kSettingPath, /*default_value=*/false);
+  bool out_value = true;
+  ASSERT_TRUE(
+      user_reporting_settings_->GetReportingEnabled(kSettingPath, &out_value));
+  EXPECT_FALSE(out_value);
+
+  // Update setting value and ensure the next fetch returns the updated value.
+  profile_->GetPrefs()->SetBoolean(kSettingPath, true);
+  ASSERT_TRUE(user_reporting_settings_->GetBoolean(kSettingPath, &out_value));
+  EXPECT_TRUE(out_value);
+}
+
 TEST_F(UserReportingSettingsTest, GetInteger) {
   profile_->GetTestingPrefService()->registry()->RegisterIntegerPref(
       kSettingPath, /*default_value=*/0);
@@ -143,6 +159,24 @@
   EXPECT_THAT(out_value->front().GetString(), Eq(kListSettingItem));
 }
 
+TEST_F(UserReportingSettingsTest, GetReportingEnabled_List) {
+  profile_->GetTestingPrefService()->registry()->RegisterListPref(
+      kSettingPath, /*default_value=*/base::Value::List());
+  bool out_value = true;
+  ASSERT_TRUE(
+      user_reporting_settings_->GetReportingEnabled(kSettingPath, &out_value));
+  EXPECT_FALSE(out_value);
+
+  // Update setting value and ensure the next fetch returns the updated value.
+  static constexpr char kListSettingItem[] = "item";
+  base::Value::List new_value;
+  new_value.Append(kListSettingItem);
+  profile_->GetPrefs()->SetList(kSettingPath, std::move(new_value));
+  ASSERT_TRUE(
+      user_reporting_settings_->GetReportingEnabled(kSettingPath, &out_value));
+  EXPECT_TRUE(out_value);
+}
+
 TEST_F(UserReportingSettingsTest, ObserveBooleanSetting) {
   profile_->GetTestingPrefService()->registry()->RegisterBooleanPref(
       kSettingPath, /*default_value=*/false);
diff --git a/chrome/browser/dips/cookie_access_filter.cc b/chrome/browser/dips/cookie_access_filter.cc
index 5dcf819..2751b12e 100644
--- a/chrome/browser/dips/cookie_access_filter.cc
+++ b/chrome/browser/dips/cookie_access_filter.cc
@@ -5,12 +5,13 @@
 #include "chrome/browser/dips/cookie_access_filter.h"
 
 #include "base/strings/string_piece.h"
+#include "chrome/browser/dips/dips_utils.h"
 
 CookieAccessFilter::CookieAccessFilter() = default;
 CookieAccessFilter::~CookieAccessFilter() = default;
 
 void CookieAccessFilter::AddAccess(const GURL& url, CookieOperation op) {
-  CookieAccessType t = ToCookieAccessType(op);
+  SiteDataAccessType t = ToSiteDataAccessType(op);
   if (!accesses_.empty() && accesses_.back().url == url) {
     // Coalesce accesses for the same URL. They may have come from separate
     // visits, but we can't distinguish them from redundant calls, which are
@@ -34,11 +35,11 @@
 // multiple times, even consecutively, in a single redirect chain.
 //
 // To handle that corner case (imperfectly), if the same URL appears multiple
-// times in a row, it will get the same CookieAccessType for all of them.
+// times in a row, it will get the same SiteDataAccessType for all of them.
 bool CookieAccessFilter::Filter(const std::vector<GURL>& urls,
-                                std::vector<CookieAccessType>* result) const {
+                                std::vector<SiteDataAccessType>* result) const {
   result->clear();
-  result->resize(urls.size(), CookieAccessType::kNone);
+  result->resize(urls.size(), SiteDataAccessType::kNone);
 
   size_t url_idx = 0;
   size_t access_idx = 0;
@@ -82,6 +83,6 @@
   }
 
   // Otherwise, fill the entire result vector with kUnknown and return false.
-  std::fill(result->begin(), result->end(), CookieAccessType::kUnknown);
+  std::fill(result->begin(), result->end(), SiteDataAccessType::kUnknown);
   return false;
 }
diff --git a/chrome/browser/dips/cookie_access_filter.h b/chrome/browser/dips/cookie_access_filter.h
index 1b1a98e..f1784cc 100644
--- a/chrome/browser/dips/cookie_access_filter.h
+++ b/chrome/browser/dips/cookie_access_filter.h
@@ -29,7 +29,7 @@
   // kUnknown. (Note: this depends on the order of previous calls to
   // AddAccess()).
   bool Filter(const std::vector<GURL>& urls,
-              std::vector<CookieAccessType>* result) const;
+              std::vector<SiteDataAccessType>* result) const;
 
   // Returns true iff AddAccess() has never been called.
   bool is_empty() const { return accesses_.empty(); }
@@ -37,7 +37,7 @@
  private:
   struct CookieAccess {
     GURL url;
-    CookieAccessType type = CookieAccessType::kUnknown;
+    SiteDataAccessType type = SiteDataAccessType::kUnknown;
   };
 
   // We use a vector rather than a set of URLs because order can matter. If the
diff --git a/chrome/browser/dips/cookie_access_filter_unittest.cc b/chrome/browser/dips/cookie_access_filter_unittest.cc
index e48e194..a05e9f7 100644
--- a/chrome/browser/dips/cookie_access_filter_unittest.cc
+++ b/chrome/browser/dips/cookie_access_filter_unittest.cc
@@ -8,23 +8,23 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(CookieAccessType, BitwiseOrOperator) {
-  ASSERT_EQ(CookieAccessType::kRead,
-            CookieAccessType::kNone | CookieAccessType::kRead);
+  ASSERT_EQ(SiteDataAccessType::kRead,
+            SiteDataAccessType::kNone | SiteDataAccessType::kRead);
 
-  ASSERT_EQ(CookieAccessType::kWrite,
-            CookieAccessType::kNone | CookieAccessType::kWrite);
+  ASSERT_EQ(SiteDataAccessType::kWrite,
+            SiteDataAccessType::kNone | SiteDataAccessType::kWrite);
 
-  ASSERT_EQ(CookieAccessType::kReadWrite,
-            CookieAccessType::kRead | CookieAccessType::kWrite);
+  ASSERT_EQ(SiteDataAccessType::kReadWrite,
+            SiteDataAccessType::kRead | SiteDataAccessType::kWrite);
 
-  ASSERT_EQ(CookieAccessType::kUnknown,
-            CookieAccessType::kUnknown | CookieAccessType::kNone);
+  ASSERT_EQ(SiteDataAccessType::kUnknown,
+            SiteDataAccessType::kUnknown | SiteDataAccessType::kNone);
 
-  ASSERT_EQ(CookieAccessType::kUnknown,
-            CookieAccessType::kUnknown | CookieAccessType::kRead);
+  ASSERT_EQ(SiteDataAccessType::kUnknown,
+            SiteDataAccessType::kUnknown | SiteDataAccessType::kRead);
 
-  ASSERT_EQ(CookieAccessType::kUnknown,
-            CookieAccessType::kUnknown | CookieAccessType::kWrite);
+  ASSERT_EQ(SiteDataAccessType::kUnknown,
+            SiteDataAccessType::kUnknown | SiteDataAccessType::kWrite);
 }
 
 TEST(CookieAccessFilter, NoAccesses) {
@@ -32,10 +32,10 @@
   GURL url2("http://google.com");
   CookieAccessFilter filter;
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kNone,
-                                           CookieAccessType::kNone));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kNone,
+                                           SiteDataAccessType::kNone));
 }
 
 TEST(CookieAccessFilter, OneRead_Former) {
@@ -44,10 +44,10 @@
   CookieAccessFilter filter;
   filter.AddAccess(url1, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kRead,
-                                           CookieAccessType::kNone));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kRead,
+                                           SiteDataAccessType::kNone));
 }
 
 TEST(CookieAccessFilter, OneRead_Latter) {
@@ -56,10 +56,10 @@
   CookieAccessFilter filter;
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kNone,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kNone,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, OneWrite) {
@@ -68,10 +68,10 @@
   CookieAccessFilter filter;
   filter.AddAccess(url2, CookieOperation::kChange);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kNone,
-                                           CookieAccessType::kWrite));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kNone,
+                                           SiteDataAccessType::kWrite));
 }
 
 TEST(CookieAccessFilter, UnexpectedURL) {
@@ -80,10 +80,10 @@
   CookieAccessFilter filter;
   filter.AddAccess(GURL("http://other.com"), CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_FALSE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kUnknown,
-                                           CookieAccessType::kUnknown));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kUnknown,
+                                           SiteDataAccessType::kUnknown));
 }
 
 TEST(CookieAccessFilter, TwoReads) {
@@ -93,10 +93,10 @@
   filter.AddAccess(url1, CookieOperation::kRead);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kRead,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kRead,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceReadBeforeWrite) {
@@ -107,10 +107,10 @@
   filter.AddAccess(url1, CookieOperation::kChange);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kReadWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceReadBeforeWrite_Repeated) {
@@ -121,11 +121,11 @@
   filter.AddAccess(url1, CookieOperation::kChange);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kReadWrite,
-                                           CookieAccessType::kReadWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceWrites) {
@@ -136,10 +136,10 @@
   filter.AddAccess(url1, CookieOperation::kChange);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceWrites_Repeated) {
@@ -150,11 +150,11 @@
   filter.AddAccess(url1, CookieOperation::kChange);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kWrite,
-                                           CookieAccessType::kWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kWrite,
+                                           SiteDataAccessType::kWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceReads) {
@@ -165,10 +165,10 @@
   filter.AddAccess(url1, CookieOperation::kRead);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kRead,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kRead,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceReads_Repeated) {
@@ -179,11 +179,11 @@
   filter.AddAccess(url1, CookieOperation::kRead);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kRead,
-                                           CookieAccessType::kRead,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kRead,
+                                           SiteDataAccessType::kRead,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceWriteBeforeRead) {
@@ -194,10 +194,10 @@
   filter.AddAccess(url1, CookieOperation::kRead);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kReadWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, CoalesceWriteBeforeRead_Repeated) {
@@ -208,11 +208,11 @@
   filter.AddAccess(url1, CookieOperation::kRead);
   filter.AddAccess(url2, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url1, url2}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kReadWrite,
-                                           CookieAccessType::kReadWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kRead));
 }
 
 TEST(CookieAccessFilter, SameURLTwiceWithDifferentAccessTypes) {
@@ -224,9 +224,9 @@
   filter.AddAccess(url2, CookieOperation::kChange);
   filter.AddAccess(url1, CookieOperation::kRead);
 
-  std::vector<CookieAccessType> result;
+  std::vector<SiteDataAccessType> result;
   ASSERT_TRUE(filter.Filter({url1, url2, url1}, &result));
-  EXPECT_THAT(result, testing::ElementsAre(CookieAccessType::kWrite,
-                                           CookieAccessType::kReadWrite,
-                                           CookieAccessType::kRead));
+  EXPECT_THAT(result, testing::ElementsAre(SiteDataAccessType::kWrite,
+                                           SiteDataAccessType::kReadWrite,
+                                           SiteDataAccessType::kRead));
 }
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc
index 532c8c5..d372383 100644
--- a/chrome/browser/dips/dips_bounce_detector.cc
+++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -86,10 +86,42 @@
                 base::DefaultClock::GetInstance()) {
   issue_reporting_callback_ = base::BindRepeating(
       &DIPSWebContentsObserver::EmitDIPSIssue, weak_factory_.GetWeakPtr());
+  dips_site_data_observer_ =
+      std::make_unique<DIPSSiteDataObserver>(web_contents, this);
 }
 
 DIPSWebContentsObserver::~DIPSWebContentsObserver() = default;
 
+DIPSWebContentsObserver::DIPSSiteDataObserver::DIPSSiteDataObserver(
+    content::WebContents* web_contents,
+    DIPSWebContentsObserver* dips_web_contents_observer)
+    : content_settings::PageSpecificContentSettings::SiteDataObserver(
+          web_contents),
+      dips_web_contents_observer_(dips_web_contents_observer) {}
+
+void DIPSWebContentsObserver::DIPSSiteDataObserver::OnSiteDataAccessed(
+    const content_settings::AccessDetails& access_details) {
+  // NOTE: The current implementation is only acting on all site data types
+  // collapsed under `content_settings::SiteDataType::kStorage` with the
+  // exception of WebLocks (not monitored by the
+  // `content_settings::PageSpecificContentSettings`) as it's not persistent.
+  if (access_details.site_data_type !=
+      content_settings::SiteDataType::kStorage) {
+    return;
+  }
+
+  DCHECK(access_details.render_frame_host);
+
+  // TODO(crbug.com/1434764): handle same-site iframes.
+  if (!access_details.render_frame_host->IsInPrimaryMainFrame() ||
+      access_details.blocked_by_policy) {
+    return;
+  }
+
+  dips_web_contents_observer_->detector_.OnClientSiteDataAccessed(
+      access_details.url, ToCookieOperation(access_details.access_type));
+}
+
 const base::TimeDelta DIPSBounceDetector::kTimestampUpdateInterval =
     base::Minutes(1);
 
@@ -140,10 +172,10 @@
 void DIPSRedirectContext::AppendClientRedirect(
     DIPSRedirectInfoPtr client_redirect) {
   DCHECK_EQ(client_redirect->redirect_type, DIPSRedirectType::kClient);
-  if (client_redirect->access_type > CookieAccessType::kNone) {
+  if (client_redirect->access_type > SiteDataAccessType::kNone) {
     update_offset_ = redirects_.size();
   }
-  if (client_redirect->access_type > CookieAccessType::kRead) {
+  if (client_redirect->access_type > SiteDataAccessType::kRead) {
     redirectors_.insert(GetSiteForDIPS(client_redirect->url));
   }
   redirects_.push_back(std::move(client_redirect));
@@ -153,10 +185,10 @@
     std::vector<DIPSRedirectInfoPtr> server_redirects) {
   for (auto& redirect : server_redirects) {
     DCHECK_EQ(redirect->redirect_type, DIPSRedirectType::kServer);
-    if (redirect->access_type > CookieAccessType::kNone) {
+    if (redirect->access_type > SiteDataAccessType::kNone) {
       update_offset_ = redirects_.size();
     }
-    if (redirect->access_type > CookieAccessType::kRead) {
+    if (redirect->access_type > SiteDataAccessType::kRead) {
       redirectors_.insert(GetSiteForDIPS(redirect->url));
     }
     redirects_.push_back(std::move(redirect));
@@ -261,7 +293,7 @@
   while (update_offset_ < redirects_.size()) {
     if (redirects_[update_offset_]->url == url) {
       redirects_[update_offset_]->access_type =
-          redirects_[update_offset_]->access_type | ToCookieAccessType(op);
+          redirects_[update_offset_]->access_type | ToSiteDataAccessType(op);
 
       // This cookie access might indicate a stateful bounce and ideally we'd
       // report an issue to notify the user, but the navigation already
@@ -295,8 +327,9 @@
   details->bounce_tracking_issue_details =
       std::move(bounce_tracking_issue_details);
 
-  web_contents()->GetPrimaryMainFrame()->ReportInspectorIssue(
-      blink::mojom::InspectorIssueInfo::New(
+  WebContentsObserver::web_contents()
+      ->GetPrimaryMainFrame()
+      ->ReportInspectorIssue(blink::mojom::InspectorIssueInfo::New(
           blink::mojom::InspectorIssueCode::kBounceTrackingIssue,
           std::move(details)));
 }
@@ -333,11 +366,13 @@
 }
 
 const GURL& DIPSWebContentsObserver::GetLastCommittedURL() const {
-  return web_contents()->GetLastCommittedURL();
+  return WebContentsObserver::web_contents()->GetLastCommittedURL();
 }
 
 ukm::SourceId DIPSWebContentsObserver::GetPageUkmSourceId() const {
-  return web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
+  return WebContentsObserver::web_contents()
+      ->GetPrimaryMainFrame()
+      ->GetPageUkmSourceId();
 }
 
 void DIPSWebContentsObserver::HandleRedirectChain(
@@ -409,7 +444,8 @@
       now - client_detection_state_->page_load_time;
   // The delay between the previous navigation commit and the current
   // client-redirect is only tracked for stateful bounces.
-  if (client_detection_state_->cookie_access_type > CookieAccessType::kNone) {
+  if (client_detection_state_->site_data_access_type >
+      SiteDataAccessType::kNone) {
     UmaHistogramTimeToBounce(client_bounce_delay);
   }
 
@@ -420,7 +456,7 @@
       std::make_unique<DIPSRedirectInfo>(
           /*url=*/delegate_->GetLastCommittedURL(),
           /*redirect_type=*/DIPSRedirectType::kClient,
-          /*access_type=*/client_detection_state_->cookie_access_type,
+          /*access_type=*/client_detection_state_->site_data_access_type,
           /*index=*/redirect_context_.size(),
           /*source_id=*/
           delegate_->GetPageUkmSourceId(),
@@ -430,9 +466,34 @@
           client_detection_state_->last_activation_time.has_value());
 }
 
+void DIPSBounceDetector::OnClientSiteDataAccessed(const GURL& url,
+                                                  CookieOperation op) {
+  auto now = clock_->Now();
+
+  if (client_detection_state_ &&
+      GetSiteForDIPS(url) == client_detection_state_->current_site) {
+    client_detection_state_->site_data_access_type =
+        client_detection_state_->site_data_access_type |
+        ToSiteDataAccessType(op);
+
+    // To decrease the number of writes made to the database, after a site
+    // storage event (cookie write) on the page, new storage events will not
+    // be recorded for the next |kTimestampUpdateInterval|.
+    if (op == CookieOperation::kChange &&
+        ShouldUpdateTimestamp(client_detection_state_->last_storage_time,
+                              now)) {
+      client_detection_state_->last_storage_time = now;
+      delegate_->RecordEvent(DIPSRecordedEvent::kStorage, url, now);
+    }
+  } else if (op == CookieOperation::kChange) {
+    delegate_->RecordEvent(DIPSRecordedEvent::kStorage, url, now);
+  }
+}
+
 void DIPSWebContentsObserver::OnCookiesAccessed(
     content::RenderFrameHost* render_frame_host,
     const content::CookieAccessDetails& details) {
+  // TODO(crbug.com/1434764): handle same-site iframes.
   if (!render_frame_host->IsInPrimaryMainFrame() || details.blocked_by_policy ||
       !net::SiteForCookies::FromUrl(details.first_party_url)
            .IsFirstParty(details.url)) {
@@ -459,23 +520,7 @@
     return;
   }
 
-  if (client_detection_state_ &&
-      GetSiteForDIPS(url) == client_detection_state_->current_site) {
-    client_detection_state_->cookie_access_type =
-        client_detection_state_->cookie_access_type | ToCookieAccessType(op);
-
-    // To decrease the number of writes made to the database, after a site
-    // storage event (cookie write) on the page, new storage events will not
-    // be recorded for the next |kTimestampUpdateInterval|.
-    if (op == CookieOperation::kChange &&
-        ShouldUpdateTimestamp(client_detection_state_->last_storage_time,
-                              now)) {
-      client_detection_state_->last_storage_time = now;
-      delegate_->RecordEvent(DIPSRecordedEvent::kStorage, url, now);
-    }
-  } else if (op == CookieOperation::kChange) {
-    delegate_->RecordEvent(DIPSRecordedEvent::kStorage, url, now);
-  }
+  OnClientSiteDataAccessed(url, op);
 }
 
 void DIPSWebContentsObserver::OnCookiesAccessed(
@@ -540,7 +585,7 @@
   }
 
   std::vector<DIPSRedirectInfoPtr> redirects;
-  std::vector<CookieAccessType> access_types;
+  std::vector<SiteDataAccessType> access_types;
   server_state->filter.Filter(navigation_handle->GetRedirectChain(),
                               &access_types);
 
@@ -572,7 +617,7 @@
     // The last entry in navigation_handle->GetRedirectChain() is actually the
     // page being committed (i.e., not a redirect). If its HTTP request or
     // response accessed cookies, record this in our client detection state.
-    client_detection_state_->cookie_access_type = access_types.back();
+    client_detection_state_->site_data_access_type = access_types.back();
   }
 }
 
@@ -618,6 +663,7 @@
 }
 
 void DIPSWebContentsObserver::WebContentsDestroyed() {
+  dips_site_data_observer_.reset();
   detector_.BeforeDestruction();
 }
 
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h
index ca62741..755af45 100644
--- a/chrome/browser/dips/dips_bounce_detector.h
+++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -19,6 +19,7 @@
 #include "chrome/browser/dips/dips_redirect_info.h"
 #include "chrome/browser/dips/dips_service.h"
 #include "chrome/browser/dips/dips_utils.h"
+#include "components/content_settings/browser/page_specific_content_settings.h"
 #include "content/public/browser/cookie_access_details.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/navigation_handle_user_data.h"
@@ -55,7 +56,7 @@
   base::TimeTicks page_load_time;
   absl::optional<base::Time> last_activation_time;
   absl::optional<base::Time> last_storage_time;
-  CookieAccessType cookie_access_type = CookieAccessType::kUnknown;
+  SiteDataAccessType site_data_access_type = SiteDataAccessType::kUnknown;
 };
 
 // Either the URL navigated away from (starting a new chain), or the client-side
@@ -202,6 +203,7 @@
   void SetClockForTesting(base::Clock* clock) { clock_ = clock; }
   // The following methods are based on WebContentsObserver, simplified.
   void DidStartNavigation(DIPSNavigationHandle* navigation_handle);
+  void OnClientSiteDataAccessed(const GURL& url, CookieOperation op);
   void OnClientCookiesAccessed(const GURL& url, CookieOperation op);
   void OnServerCookiesAccessed(DIPSNavigationHandle* navigation_handle,
                                const GURL& url,
@@ -297,12 +299,31 @@
       content::RenderFrameHost* render_frame_host) override;
   void WebContentsDestroyed() override;
 
+  class DIPSSiteDataObserver
+      : public content_settings::PageSpecificContentSettings::SiteDataObserver {
+   public:
+    DIPSSiteDataObserver(content::WebContents* web_contents,
+                         DIPSWebContentsObserver* dips_web_contents_observer);
+
+    DIPSSiteDataObserver(const DIPSSiteDataObserver&) = delete;
+    DIPSSiteDataObserver& operator=(const DIPSSiteDataObserver&) = delete;
+
+   private:
+    // Start SiteDataObserver overrides:
+    void OnSiteDataAccessed(
+        const content_settings::AccessDetails& access_details) override;
+    // End SiteDataObserver overrides.
+
+    raw_ptr<DIPSWebContentsObserver> dips_web_contents_observer_;
+  };
+
   // raw_ptr<> is safe here because DIPSService is a KeyedService, associated
   // with the BrowserContext/Profile which will outlive the WebContents that
   // DIPSWebContentsObserver is observing.
   raw_ptr<DIPSService> dips_service_;
   DIPSBounceDetector detector_;
   DIPSIssueReportingCallback issue_reporting_callback_;
+  std::unique_ptr<DIPSSiteDataObserver> dips_site_data_observer_;
 
   base::WeakPtrFactory<DIPSWebContentsObserver> weak_factory_{this};
 
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index 0c5befb..8decb20 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -2,14 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/test/bind.h"
 #include "chrome/browser/dips/dips_bounce_detector.h"
 
+#include <memory>
+#include <string>
+
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
+#include "base/path_service.h"
 #include "base/strings/escape.h"
 #include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/dips/dips_service.h"
 #include "chrome/browser/dips/dips_service_factory.h"
@@ -19,6 +23,8 @@
 #include "chrome/test/base/chrome_test_utils.h"
 #include "content/public/browser/cookie_access_details.h"
 #include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_paths.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/hit_test_region_observer.h"
@@ -32,6 +38,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/blink/public/common/switches.h"
 #include "third_party/metrics_proto/ukm/source.pb.h"
+#include "url/gurl.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "chrome/test/base/android/android_browser_test.h"
@@ -51,6 +58,89 @@
 using ukm::builders::DIPS_Redirect;
 
 namespace {
+constexpr char kStorageAccessScript[] = R"(
+    async function accessDatabase() {
+      var my_db = openDatabase('my_db', '1.0', 'description', 1024);
+      var num_rows;
+      await new Promise((resolve, reject) => {
+        my_db.transaction((tx) => {
+          tx.executeSql('CREATE TABLE IF NOT EXISTS tbl (id unique, data)');
+          tx.executeSql('INSERT INTO tbl (id, data) VALUES (1, "foo")');
+          tx.executeSql('SELECT * FROM tbl', [], (tx, results) => {
+            num_rows = results.rows.length;
+          });
+        }, reject, resolve);
+      });
+      if(num_rows <= 0) {throw new Error('Failed to access!')}
+    }
+
+    function accessLocalStorage() {
+      localStorage.setItem('foo', 'bar');
+      return localStorage.getItem('foo');
+    }
+
+    function accessSessionStorage() {
+      sessionStorage.setItem('foo', 'bar');
+      return sessionStorage.getItem('foo') == 'bar';
+    }
+
+    async function accessFileSystem() {
+      const fs = await new Promise((resolve, reject) => {
+        window.webkitRequestFileSystem(TEMPORARY, 1024, resolve, reject);
+      });
+      return new Promise((resolve, reject) => {
+        fs.root.getFile('foo.txt', {create: true, exclusive: true}, resolve,
+          reject);
+      });
+    }
+
+    function accessIndexedDB() {
+      var request = indexedDB.open('my_db', 2);
+
+      request.onupgradeneeded = () => {
+        request.result.createObjectStore('store');
+      }
+      return new Promise((resolve) => {
+        request.onsuccess = () => {
+          request.result.close();
+          resolve(true);
+        }
+        request.onerror = () => {throw new Error('Failed to access!')}
+      });
+    }
+
+    function accessCache() {
+      return caches.open("cache")
+      .then((cache) => cache.put("/foo", new Response("bar")))
+      .then(() => true)
+      .catch(() => {throw new Error('Failed to access!')});
+    }
+
+    // Placeholder for execution statement.
+    access%s();
+  )";
+
+using StorageType =
+    content_settings::mojom::ContentSettingsManager::StorageType;
+
+inline const std::string StorageTypeTestName(const StorageType& type) {
+  switch (type) {
+    case StorageType::DATABASE:
+      return "Database";
+    case StorageType::LOCAL_STORAGE:
+      return "LocalStorage";
+    case StorageType::SESSION_STORAGE:
+      return "SessionStorage";
+    case StorageType::FILE_SYSTEM:
+      return "FileSystem";
+    case StorageType::INDEXED_DB:
+      return "IndexedDB";
+    case StorageType::CACHE:
+      return "Cache";
+    case StorageType::WEB_LOCKS:
+      return "WebLocks";
+  }
+}
 
 // Returns a simplified URL representation for ease of comparison in tests.
 // Just host+path.
@@ -64,7 +154,7 @@
   redirects->push_back(base::StringPrintf(
       "[%d/%d] %s -> %s (%s) -> %s", redirect.index + 1, chain.length,
       FormatURL(chain.initial_url).c_str(), FormatURL(redirect.url).c_str(),
-      CookieAccessTypeToString(redirect.access_type).data(),
+      SiteDataAccessTypeToString(redirect.access_type).data(),
       FormatURL(chain.final_url).c_str()));
 }
 
@@ -100,21 +190,46 @@
   // So WebContentsUserData::CreateForWebContents() can call the constructor.
   friend class content::WebContentsUserData<WCOCallbackLogger>;
 
+  // Start WebContentsObserver overrides:
   void DidStartNavigation(NavigationHandle* navigation_handle) override;
   void OnCookiesAccessed(content::RenderFrameHost* render_frame_host,
                          const content::CookieAccessDetails& details) override;
   void OnCookiesAccessed(NavigationHandle* navigation_handle,
                          const content::CookieAccessDetails& details) override;
   void DidFinishNavigation(NavigationHandle* navigation_handle) override;
+  void WebContentsDestroyed() override;
+  // End WebContentsObserver overrides.
+
+  class DIPSSiteDataObserver
+      : public content_settings::PageSpecificContentSettings::SiteDataObserver {
+   public:
+    DIPSSiteDataObserver(content::WebContents* web_contents,
+                         WCOCallbackLogger* dips_web_contents_observer);
+
+    DIPSSiteDataObserver(const DIPSSiteDataObserver&) = delete;
+    DIPSSiteDataObserver& operator=(const DIPSSiteDataObserver&) = delete;
+
+   private:
+    // Start SiteDataObserver overrides:
+    void OnSiteDataAccessed(
+        const content_settings::AccessDetails& access_details) override;
+    // End SiteDataObserver overrides.
+
+    raw_ptr<WCOCallbackLogger> wco_callback_logger_;
+  };
 
   std::vector<std::string> log_;
+  std::unique_ptr<DIPSSiteDataObserver> dips_site_data_observer_;
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
 WCOCallbackLogger::WCOCallbackLogger(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
-      content::WebContentsUserData<WCOCallbackLogger>(*web_contents) {}
+      content::WebContentsUserData<WCOCallbackLogger>(*web_contents) {
+  dips_site_data_observer_ =
+      std::make_unique<DIPSSiteDataObserver>(web_contents, this);
+}
 
 void WCOCallbackLogger::DidStartNavigation(
     NavigationHandle* navigation_handle) {
@@ -160,6 +275,67 @@
                          FormatURL(navigation_handle->GetURL()).c_str()));
 }
 
+void WCOCallbackLogger::WebContentsDestroyed() {
+  dips_site_data_observer_.reset();
+}
+
+WCOCallbackLogger::DIPSSiteDataObserver::DIPSSiteDataObserver(
+    content::WebContents* web_contents,
+    WCOCallbackLogger* wco_callback_logger)
+    : content_settings::PageSpecificContentSettings::SiteDataObserver(
+          web_contents),
+      wco_callback_logger_(wco_callback_logger) {}
+
+inline std::string SiteDataTypeToString(
+    const content_settings::SiteDataType& type) {
+  switch (type) {
+    case content_settings::SiteDataType::kUnknown:
+      return "Unknown";
+    case content_settings::SiteDataType::kStorage:
+      return "Storage";
+    case content_settings::SiteDataType::kCookies:
+      return "Cookies";
+    case content_settings::SiteDataType::kServiceWorker:
+      return "ServiceWorker";
+    case content_settings::SiteDataType::kSharedWorker:
+      return "SharedWorker";
+    case content_settings::SiteDataType::kInterestGroup:
+      return "InterestGroup";
+    case content_settings::SiteDataType::kTopic:
+      return "Topics";
+    case content_settings::SiteDataType::kTrustToken:
+      return "TrustToken";
+  }
+}
+
+inline std::string AccessTypeToString(content_settings::AccessType type) {
+  switch (type) {
+    case content_settings::AccessType::kUnknown:
+      return "Unknown";
+    case content_settings::AccessType::kRead:
+      return "Read";
+    case content_settings::AccessType::kWrite:
+      return "Write";
+  }
+}
+
+void WCOCallbackLogger::DIPSSiteDataObserver::OnSiteDataAccessed(
+    const content_settings::AccessDetails& access_details) {
+  // Avoids logging notification from the PSCS that are due to cookie accesses,
+  // in order not to impact the other cookie access notification logs from the
+  // `WebContentsObserver`.
+  if (access_details.site_data_type ==
+      content_settings::SiteDataType::kCookies) {
+    return;
+  }
+
+  wco_callback_logger_->log_.push_back(base::StringPrintf(
+      "OnSiteDataAccessed(AccessDetails, %s: %s: %s)",
+      SiteDataTypeToString(access_details.site_data_type).c_str(),
+      AccessTypeToString(access_details.access_type).c_str(),
+      FormatURL(access_details.url).c_str()));
+}
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(WCOCallbackLogger);
 
 class DIPSBounceDetectorBrowserTest : public PlatformBrowserTest {
@@ -277,6 +453,16 @@
         embedded_test_server()->GetURL("a.test", "/title1.html")));
   }
 
+  [[nodiscard]] bool AccessStorage(content::RenderFrameHost* frame,
+                                   const StorageType& type) {
+    return content::ExecJs(
+        frame,
+        base::StringPrintf(kStorageAccessScript,
+                           StorageTypeTestName(type).c_str()),
+        content::EXECUTE_SCRIPT_NO_USER_GESTURE,
+        /*world_id=*/1);
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 
@@ -284,6 +470,98 @@
       nullptr;
 };
 
+class DIPSSiteDataAccessDetectorTest
+    : public DIPSBounceDetectorBrowserTest,
+      public testing::WithParamInterface<StorageType> {
+ public:
+  DIPSSiteDataAccessDetectorTest(const DIPSSiteDataAccessDetectorTest&) =
+      delete;
+  DIPSSiteDataAccessDetectorTest& operator=(
+      const DIPSSiteDataAccessDetectorTest&) = delete;
+
+  DIPSSiteDataAccessDetectorTest()
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
+
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    base::FilePath path;
+    base::PathService::Get(content::DIR_TEST_DATA, &path);
+    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+    https_server_.ServeFilesFromDirectory(path);
+    https_server_.AddDefaultHandlers(
+        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
+    ASSERT_TRUE(https_server_.Start());
+  }
+
+  auto* TestServer() { return &https_server_; }
+
+ private:
+  net::test_server::EmbeddedTestServer https_server_;
+};
+
+IN_PROC_BROWSER_TEST_P(DIPSSiteDataAccessDetectorTest,
+                       DetectSiteDataAccess_Storages) {
+  // Start logging `WebContentsObserver` callbacks.
+  WCOCallbackLogger::CreateForWebContents(GetActiveWebContents());
+  auto* logger = WCOCallbackLogger::FromWebContents(GetActiveWebContents());
+
+  EXPECT_TRUE(content::NavigateToURLFromRenderer(
+      GetActiveWebContents()->GetPrimaryMainFrame(),
+      TestServer()->GetURL("a.test", "/title1.html")));
+
+  EXPECT_TRUE(
+      AccessStorage(GetActiveWebContents()->GetPrimaryMainFrame(), GetParam()));
+
+  EXPECT_THAT(
+      logger->log(),
+      testing::ContainerEq(std::vector<std::string>({
+          "DidStartNavigation(a.test/title1.html)",
+          "DidFinishNavigation(a.test/title1.html)",
+          "OnSiteDataAccessed(AccessDetails, Storage: Unknown: a.test/)",
+      })));
+}
+
+// WeLocks accesses aren't monitored by the `PageSpecificContentSettings` as
+// there are not persistent.
+INSTANTIATE_TEST_SUITE_P(All,
+                         DIPSSiteDataAccessDetectorTest,
+                         ::testing::Values(StorageType::DATABASE,
+                                           StorageType::LOCAL_STORAGE,
+                                           StorageType::SESSION_STORAGE,
+                                           StorageType::CACHE,
+                                           StorageType::FILE_SYSTEM,
+                                           StorageType::INDEXED_DB));
+
+IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
+                       DetectStatefulBounce_ClientRedirect_SiteDataAccess) {
+  std::vector<std::string> redirects;
+  StartAppendingRedirectsTo(&redirects);
+
+  // Navigate to the initial page, a.test.
+  ASSERT_TRUE(content::NavigateToURL(
+      GetActiveWebContents(),
+      embedded_test_server()->GetURL("a.test", "/title1.html")));
+
+  // Navigate with a click (not considered to be redirect) to b.test.
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      GetActiveWebContents(),
+      embedded_test_server()->GetURL("b.test", "/title1.html")));
+
+  EXPECT_TRUE(AccessStorage(GetActiveWebContents()->GetPrimaryMainFrame(),
+                            StorageType::LOCAL_STORAGE));
+
+  // Navigate without a click (considered a client-redirect) to c.test.
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      GetActiveWebContents(),
+      embedded_test_server()->GetURL("c.test", "/title1.html")));
+
+  EndRedirectChain();
+
+  EXPECT_THAT(redirects,
+              ElementsAre(("[1/1] a.test/title1.html -> b.test/title1.html "
+                           "(Write) -> c.test/title1.html")));
+}
+
 // The timing of WCO::OnCookiesAccessed() execution is unpredictable for
 // redirects. Sometimes it's called before WCO::DidRedirectNavigation(), and
 // sometimes after. Therefore DIPSBounceDetector needs to know when it's safe to
diff --git a/chrome/browser/dips/dips_bounce_detector_unittest.cc b/chrome/browser/dips/dips_bounce_detector_unittest.cc
index 63cbfc2..b4836bf 100644
--- a/chrome/browser/dips/dips_bounce_detector_unittest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_unittest.cc
@@ -58,7 +58,7 @@
   redirects->push_back(base::StringPrintf(
       "[%d/%d] %s -> %s (%s) -> %s", redirect.index + 1, chain.length,
       FormatURL(chain.initial_url).c_str(), FormatURL(redirect.url).c_str(),
-      CookieAccessTypeToString(redirect.access_type).data(),
+      SiteDataAccessTypeToString(redirect.access_type).data(),
       FormatURL(chain.final_url).c_str()));
 }
 
@@ -80,7 +80,7 @@
     chain->cookie_mode = DIPSCookieMode::kStandard;
     for (auto& redirect : redirects) {
       redirect->has_interaction = GetSiteHasInteraction(redirect->url);
-      DCHECK(redirect->access_type != CookieAccessType::kUnknown);
+      DCHECK(redirect->access_type != SiteDataAccessType::kUnknown);
       AppendRedirect(&redirects_, *redirect, *chain);
 
       DIPSService::HandleRedirectForTesting(
@@ -962,7 +962,7 @@
   EXPECT_THAT(
       ukm_entries[0].metrics,
       ElementsAre(Pair("ClientBounceDelay", 2),
-                  Pair("CookieAccessType", (int)CookieAccessType::kRead),
+                  Pair("CookieAccessType", (int)SiteDataAccessType::kRead),
                   Pair("HasStickyActivation", false),
                   Pair("InitialAndFinalSitesSame", false),
                   Pair("RedirectAndFinalSiteSame", false),
@@ -976,7 +976,7 @@
   EXPECT_THAT(
       ukm_entries[1].metrics,
       ElementsAre(Pair("ClientBounceDelay", 0),
-                  Pair("CookieAccessType", (int)CookieAccessType::kWrite),
+                  Pair("CookieAccessType", (int)SiteDataAccessType::kWrite),
                   Pair("HasStickyActivation", false),
                   Pair("InitialAndFinalSitesSame", false),
                   Pair("RedirectAndFinalSiteSame", false),
@@ -998,7 +998,7 @@
 std::vector<DIPSRedirectInfoPtr> MakeServerRedirects(
     size_t offset,
     std::vector<std::string> urls,
-    CookieAccessType access_type = CookieAccessType::kReadWrite) {
+    SiteDataAccessType access_type = SiteDataAccessType::kReadWrite) {
   std::vector<DIPSRedirectInfoPtr> redirects;
   for (size_t i = 0; i < urls.size(); i++) {
     redirects.push_back(std::make_unique<DIPSRedirectInfo>(
@@ -1015,7 +1015,7 @@
 DIPSRedirectInfoPtr MakeClientRedirect(
     size_t offset,
     std::string url,
-    CookieAccessType access_type = CookieAccessType::kReadWrite) {
+    SiteDataAccessType access_type = SiteDataAccessType::kReadWrite) {
   return std::make_unique<DIPSRedirectInfo>(
       /*url=*/GURL(url),
       /*redirect_type=*/DIPSRedirectType::kClient,
@@ -1039,9 +1039,9 @@
                             result_listener);
 }
 
-MATCHER_P(HasCookieAccessType, access_type, "") {
+MATCHER_P(HasSiteDataAccessType, access_type, "") {
   *result_listener << "whose access_type is "
-                   << CookieAccessTypeToString(arg->access_type);
+                   << SiteDataAccessTypeToString(arg->access_type);
   return ExplainMatchResult(Eq(access_type), arg->access_type, result_listener);
 }
 
@@ -1301,7 +1301,7 @@
       GURL("http://a.test/"),
       MakeServerRedirects(
           0, {"http://b.test/", "http://c.test/", "http://d.test/"},
-          CookieAccessType::kNone),
+          SiteDataAccessType::kNone),
       GURL("http://e.test/"));
 
   EXPECT_TRUE(context.AddLateCookieAccess(GURL("http://b.test/"),
@@ -1320,9 +1320,9 @@
                                            CookieOperation::kRead));
 
   context.AppendCommitted(
-      MakeClientRedirect(3, "http://e.test/", CookieAccessType::kNone),
+      MakeClientRedirect(3, "http://e.test/", SiteDataAccessType::kNone),
       MakeServerRedirects(4, {"http://f.test/", "http://g.test/"},
-                          CookieAccessType::kRead),
+                          SiteDataAccessType::kRead),
       GURL("http://h.test/"));
 
   // This late "write" will be merged with the "read" already recorded.
@@ -1330,8 +1330,8 @@
                                           CookieOperation::kChange));
 
   context.AppendCommitted(
-      MakeClientRedirect(6, "http://h.test/", CookieAccessType::kNone),
-      MakeServerRedirects(7, {"http://i.test/"}, CookieAccessType::kRead),
+      MakeClientRedirect(6, "http://h.test/", SiteDataAccessType::kNone),
+      MakeServerRedirects(7, {"http://i.test/"}, SiteDataAccessType::kRead),
       GURL("http://j.test/"));
 
   // Can't modify h.test since i.test already has a known cookie access.
@@ -1347,19 +1347,19 @@
   EXPECT_THAT(
       chains[0].second,
       ElementsAre(AllOf(HasUrl("http://b.test/"),
-                        HasCookieAccessType(CookieAccessType::kWrite)),
+                        HasSiteDataAccessType(SiteDataAccessType::kWrite)),
                   AllOf(HasUrl("http://c.test/"),
-                        HasCookieAccessType(CookieAccessType::kNone)),
+                        HasSiteDataAccessType(SiteDataAccessType::kNone)),
                   AllOf(HasUrl("http://d.test/"),
-                        HasCookieAccessType(CookieAccessType::kReadWrite)),
+                        HasSiteDataAccessType(SiteDataAccessType::kReadWrite)),
                   AllOf(HasUrl("http://e.test/"),
-                        HasCookieAccessType(CookieAccessType::kNone)),
+                        HasSiteDataAccessType(SiteDataAccessType::kNone)),
                   AllOf(HasUrl("http://f.test/"),
-                        HasCookieAccessType(CookieAccessType::kRead)),
+                        HasSiteDataAccessType(SiteDataAccessType::kRead)),
                   AllOf(HasUrl("http://g.test/"),
-                        HasCookieAccessType(CookieAccessType::kReadWrite)),
+                        HasSiteDataAccessType(SiteDataAccessType::kReadWrite)),
                   AllOf(HasUrl("http://h.test/"),
-                        HasCookieAccessType(CookieAccessType::kNone)),
+                        HasSiteDataAccessType(SiteDataAccessType::kNone)),
                   AllOf(HasUrl("http://i.test/"),
-                        HasCookieAccessType(CookieAccessType::kRead))));
+                        HasSiteDataAccessType(SiteDataAccessType::kRead))));
 }
diff --git a/chrome/browser/dips/dips_redirect_info.cc b/chrome/browser/dips/dips_redirect_info.cc
index 835b57e..fa5d4ead 100644
--- a/chrome/browser/dips/dips_redirect_info.cc
+++ b/chrome/browser/dips/dips_redirect_info.cc
@@ -18,7 +18,7 @@
 
 DIPSRedirectInfo::DIPSRedirectInfo(const GURL& url,
                                    DIPSRedirectType redirect_type,
-                                   CookieAccessType access_type,
+                                   SiteDataAccessType access_type,
                                    int index,
                                    ukm::SourceId source_id,
                                    base::Time time)
@@ -37,7 +37,7 @@
 
 DIPSRedirectInfo::DIPSRedirectInfo(const GURL& url,
                                    DIPSRedirectType redirect_type,
-                                   CookieAccessType access_type,
+                                   SiteDataAccessType access_type,
                                    int index,
                                    ukm::SourceId source_id,
                                    base::Time time,
diff --git a/chrome/browser/dips/dips_redirect_info.h b/chrome/browser/dips/dips_redirect_info.h
index 35a6826..3d44c0a4 100644
--- a/chrome/browser/dips/dips_redirect_info.h
+++ b/chrome/browser/dips/dips_redirect_info.h
@@ -43,14 +43,14 @@
   // Constructor for server-side redirects.
   DIPSRedirectInfo(const GURL& url,
                    DIPSRedirectType redirect_type,
-                   CookieAccessType access_type,
+                   SiteDataAccessType access_type,
                    int index,
                    ukm::SourceId source_id,
                    base::Time time);
   // Constructor for client-side redirects.
   DIPSRedirectInfo(const GURL& url,
                    DIPSRedirectType redirect_type,
-                   CookieAccessType access_type,
+                   SiteDataAccessType access_type,
                    int index,
                    ukm::SourceId source_id,
                    base::Time time,
@@ -62,7 +62,8 @@
 
   const GURL url;
   const DIPSRedirectType redirect_type;
-  CookieAccessType access_type;  // may be updated by late cookie notifications
+  SiteDataAccessType
+      access_type;  // may be updated by late cookie notifications
   // Index of this URL within the overall chain.
   const int index;
   const ukm::SourceId source_id;
diff --git a/chrome/browser/dips/dips_service.cc b/chrome/browser/dips/dips_service.cc
index ca95fce..f03ddc8c 100644
--- a/chrome/browser/dips/dips_service.cc
+++ b/chrome/browser/dips/dips_service.cc
@@ -67,22 +67,22 @@
   return std::vector(unique_sites.begin(), unique_sites.end());
 }
 
-RedirectCategory ClassifyRedirect(CookieAccessType access,
+RedirectCategory ClassifyRedirect(SiteDataAccessType access,
                                   bool has_interaction) {
   switch (access) {
-    case CookieAccessType::kUnknown:
+    case SiteDataAccessType::kUnknown:
       return has_interaction ? RedirectCategory::kUnknownCookies_HasEngagement
                              : RedirectCategory::kUnknownCookies_NoEngagement;
-    case CookieAccessType::kNone:
+    case SiteDataAccessType::kNone:
       return has_interaction ? RedirectCategory::kNoCookies_HasEngagement
                              : RedirectCategory::kNoCookies_NoEngagement;
-    case CookieAccessType::kRead:
+    case SiteDataAccessType::kRead:
       return has_interaction ? RedirectCategory::kReadCookies_HasEngagement
                              : RedirectCategory::kReadCookies_NoEngagement;
-    case CookieAccessType::kWrite:
+    case SiteDataAccessType::kWrite:
       return has_interaction ? RedirectCategory::kWriteCookies_HasEngagement
                              : RedirectCategory::kWriteCookies_NoEngagement;
-    case CookieAccessType::kReadWrite:
+    case SiteDataAccessType::kReadWrite:
       return has_interaction ? RedirectCategory::kReadWriteCookies_HasEngagement
                              : RedirectCategory::kReadWriteCookies_NoEngagement;
   }
@@ -384,10 +384,10 @@
   }
 
   // Record this bounce in the DIPS database.
-  if (redirect.access_type != CookieAccessType::kUnknown) {
+  if (redirect.access_type != SiteDataAccessType::kUnknown) {
     record_bounce.Run(
         redirect.url, redirect.time,
-        /*stateful=*/redirect.access_type > CookieAccessType::kRead);
+        /*stateful=*/redirect.access_type > SiteDataAccessType::kRead);
   }
 
   RedirectCategory category =
diff --git a/chrome/browser/dips/dips_utils.cc b/chrome/browser/dips/dips_utils.cc
index ab155c4..ea0fc43 100644
--- a/chrome/browser/dips/dips_utils.cc
+++ b/chrome/browser/dips/dips_utils.cc
@@ -64,24 +64,25 @@
   return os << "[" << range->first << ", " << range->second << "]";
 }
 
-// CookieAccessType:
-base::StringPiece CookieAccessTypeToString(CookieAccessType type) {
+// SiteDataAccessType:
+
+base::StringPiece SiteDataAccessTypeToString(SiteDataAccessType type) {
   switch (type) {
-    case CookieAccessType::kUnknown:
+    case SiteDataAccessType::kUnknown:
       return "Unknown";
-    case CookieAccessType::kNone:
+    case SiteDataAccessType::kNone:
       return "None";
-    case CookieAccessType::kRead:
+    case SiteDataAccessType::kRead:
       return "Read";
-    case CookieAccessType::kWrite:
+    case SiteDataAccessType::kWrite:
       return "Write";
-    case CookieAccessType::kReadWrite:
+    case SiteDataAccessType::kReadWrite:
       return "ReadWrite";
   }
 }
 
-std::ostream& operator<<(std::ostream& os, CookieAccessType access_type) {
-  return os << CookieAccessTypeToString(access_type);
+std::ostream& operator<<(std::ostream& os, SiteDataAccessType access_type) {
+  return os << SiteDataAccessTypeToString(access_type);
 }
 
 // DIPSCookieMode:
diff --git a/chrome/browser/dips/dips_utils.h b/chrome/browser/dips/dips_utils.h
index 1b39e588..25e0f35 100644
--- a/chrome/browser/dips/dips_utils.h
+++ b/chrome/browser/dips/dips_utils.h
@@ -10,6 +10,7 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_piece_forward.h"
 #include "base/time/time.h"
+#include "components/content_settings/browser/page_specific_content_settings.h"
 #include "services/network/public/mojom/cookie_access_observer.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
@@ -25,9 +26,17 @@
 }
 
 // A single cookie-accessing operation (either read or write). Not to be
-// confused with CookieAccessType, which can also represent no access or both
+// confused with SiteDataAccessType, which can also represent no access or both
 // read+write.
 using CookieOperation = network::mojom::CookieAccessDetails::Type;
+inline CookieOperation ToCookieOperation(content_settings::AccessType type) {
+  switch (type) {
+    case content_settings::AccessType::kRead:
+    case content_settings::AccessType::kWrite:
+    case content_settings::AccessType::kUnknown:
+      return CookieOperation::kChange;
+  }
+}
 
 // The filename for the DIPS database.
 const base::FilePath::CharType kDIPSFilename[] = FILE_PATH_LITERAL("DIPS");
@@ -43,29 +52,27 @@
 // created, if `dips::kFeature` is NOT enabled.
 ProfileSelections GetHumanProfileSelections();
 
-// CookieAccessType:
+// SiteDataAccessType:
 // NOTE: We use this type as a bitfield, and will soon be logging it. Don't
 // change the values or add additional members.
-enum class CookieAccessType {
+enum class SiteDataAccessType {
   kUnknown = -1,
   kNone = 0,
   kRead = 1,
   kWrite = 2,
   kReadWrite = 3
 };
-
-inline CookieAccessType ToCookieAccessType(CookieOperation op) {
-  return (op == CookieOperation::kChange ? CookieAccessType::kWrite
-                                         : CookieAccessType::kRead);
+inline SiteDataAccessType ToSiteDataAccessType(CookieOperation op) {
+  return (op == CookieOperation::kChange ? SiteDataAccessType::kWrite
+                                         : SiteDataAccessType::kRead);
 }
+base::StringPiece SiteDataAccessTypeToString(SiteDataAccessType type);
+std::ostream& operator<<(std::ostream& os, SiteDataAccessType access_type);
 
-base::StringPiece CookieAccessTypeToString(CookieAccessType type);
-std::ostream& operator<<(std::ostream& os, CookieAccessType access_type);
-
-constexpr CookieAccessType operator|(CookieAccessType lhs,
-                                     CookieAccessType rhs) {
-  return static_cast<CookieAccessType>(static_cast<int>(lhs) |
-                                       static_cast<int>(rhs));
+constexpr SiteDataAccessType operator|(SiteDataAccessType lhs,
+                                       SiteDataAccessType rhs) {
+  return static_cast<SiteDataAccessType>(static_cast<int>(lhs) |
+                                         static_cast<int>(rhs));
 }
 
 // DIPSCookieMode:
@@ -161,7 +168,7 @@
   kInteraction,
 };
 
-// RedirectCategory is basically the cross-product of CookieAccessType and a
+// RedirectCategory is basically the cross-product of SiteDataAccessType and a
 // boolean value indicating site engagement. It's used in UMA enum histograms.
 //
 // These values are persisted to logs. Entries should not be renumbered and
diff --git a/chrome/browser/download/download_status_updater_lacros.cc b/chrome/browser/download/download_status_updater_lacros.cc
index 1764ac7..1fa0ee7d 100644
--- a/chrome/browser/download/download_status_updater_lacros.cc
+++ b/chrome/browser/download/download_status_updater_lacros.cc
@@ -4,22 +4,69 @@
 
 #include "chrome/browser/download/download_status_updater.h"
 
+#include "base/containers/contains.h"
+#include "chrome/browser/download/bubble/download_bubble_prefs.h"
+#include "chrome/browser/download/download_commands.h"
+#include "chrome/browser/download/download_item_model.h"
+#include "chrome/browser/download/download_ui_model.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chromeos/crosapi/mojom/download_controller.mojom.h"
 #include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "components/download/public/common/download_item_utils.h"
+#include "content/public/browser/download_item_utils.h"
 
 namespace {
 
 // Helpers ---------------------------------------------------------------------
 
-// TODO(http://b/279831939): Add more renderable metadata.
+bool IsCommandEnabled(DownloadItemModel& model,
+                      DownloadCommands::Command command) {
+  // To support other commands, we may need to update checks below to also
+  // inspect `BubbleUIInfo` subpage buttons.
+  CHECK(command == DownloadCommands::CANCEL ||
+        command == DownloadCommands::PAUSE ||
+        command == DownloadCommands::RESUME);
+
+  const bool is_download_bubble_v2_enabled =
+      download::IsDownloadBubbleV2Enabled(Profile::FromBrowserContext(
+          content::DownloadItemUtils::GetBrowserContext(
+              model.GetDownloadItem())));
+
+  // `BubbleUIInfo` contains at most one of either `CANCEL`, `PAUSE`, or
+  // `RESUME` when download bubble v2 is disabled, despite the fact that a
+  // download may be simultaneously cancellable and pausable/resumable. For
+  // this reason, do not use `BubbleUIInfo`-based determination of command
+  // enablement when download bubble v2 is disabled.
+  if (!is_download_bubble_v2_enabled) {
+    DownloadCommands commands(model.GetWeakPtr());
+    return model.IsCommandEnabled(&commands, command);
+  }
+
+  const DownloadUIModel::BubbleUIInfo info =
+      model.GetBubbleUIInfo(/*is_download_bubble_v2_enabled=*/true);
+
+  // A command is enabled if `BubbleUIInfo` contains a quick action for it. This
+  // is preferred over non-`BubbleUIInfo`-based determination of command
+  // enablement as it takes more signals into account, e.g. if the download has
+  // been marked dangerous.
+  return base::Contains(info.quick_actions, command,
+                        &DownloadUIModel::BubbleUIInfo::QuickAction::command);
+}
+
 crosapi::mojom::DownloadStatusPtr ConvertToMojoDownloadStatus(
-    const download::DownloadItem* download) {
+    download::DownloadItem* download) {
+  DownloadItemModel model(download);
   auto status = crosapi::mojom::DownloadStatus::New();
   status->guid = download->GetGuid();
   status->state = download::download_item_utils::ConvertToMojoDownloadState(
       download->GetState());
+  status->received_bytes = download->GetReceivedBytes();
+  status->total_bytes = download->GetTotalBytes();
+  status->target_file_path = download->GetTargetFilePath();
+  status->cancellable = IsCommandEnabled(model, DownloadCommands::CANCEL);
+  status->pausable = IsCommandEnabled(model, DownloadCommands::PAUSE);
+  status->resumable = IsCommandEnabled(model, DownloadCommands::RESUME);
   return status;
 }
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
index dad4c0a..0dc0038 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
@@ -23,6 +23,7 @@
 #include "components/device_signals/core/common/signals_constants.h"
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "components/enterprise/browser/device_trust/device_trust_key_manager.h"
+#include "components/policy/core/common/cloud/cloud_policy_store.h"
 #include "crypto/random.h"
 #include "crypto/unexportable_key.h"
 
@@ -30,6 +31,7 @@
 
 namespace {
 using policy::BrowserDMTokenStorage;
+using policy::CloudPolicyStore;
 
 // Size of nonce for challenge response.
 const size_t kChallengeResponseNonceBytesSize = 32;
@@ -97,9 +99,11 @@
 
 DesktopAttestationService::DesktopAttestationService(
     BrowserDMTokenStorage* dm_token_storage,
-    DeviceTrustKeyManager* key_manager)
+    DeviceTrustKeyManager* key_manager,
+    CloudPolicyStore* browser_cloud_policy_store)
     : dm_token_storage_(dm_token_storage),
       key_manager_(key_manager),
+      browser_cloud_policy_store_(browser_cloud_policy_store),
       background_task_runner_(base::ThreadPool::CreateTaskRunner(
           {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
@@ -186,6 +190,12 @@
   key_info.set_dm_token(dm_token.value());
   key_info.set_device_id(dm_token_storage_->RetrieveClientId());
 
+  if (browser_cloud_policy_store_ &&
+      browser_cloud_policy_store_->has_policy()) {
+    const auto* policy = browser_cloud_policy_store_->policy();
+    key_info.set_customer_id(policy->obfuscated_customer_id());
+  }
+
   if (exported_public_key) {
     key_info.set_browser_instance_public_key(exported_public_key.value());
   }
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
index a5e7244..60b024e3 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
@@ -19,6 +19,7 @@
 
 namespace policy {
 class BrowserDMTokenStorage;
+class CloudPolicyStore;
 }  // namespace policy
 
 namespace enterprise_connectors {
@@ -32,7 +33,8 @@
  public:
   explicit DesktopAttestationService(
       policy::BrowserDMTokenStorage* dm_token_storage,
-      DeviceTrustKeyManager* key_manager);
+      DeviceTrustKeyManager* key_manager,
+      policy::CloudPolicyStore* browser_cloud_policy_store);
   ~DesktopAttestationService() override;
 
   // AttestationService:
@@ -78,6 +80,9 @@
   // respects the browser shutdown sequence.
   raw_ptr<DeviceTrustKeyManager> key_manager_;
 
+  // Used for retrieving a managed devices customer ID.
+  const raw_ptr<policy::CloudPolicyStore> browser_cloud_policy_store_;
+
   // Runner for tasks needed to be run in the background.
   scoped_refptr<base::TaskRunner> background_task_runner_;
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
index 9713d9a..7b429ab 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
 #include "components/device_signals/core/common/signals_constants.h"
 #include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
+#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -71,6 +72,7 @@
 constexpr char kDisplayName[] = "display-name";
 constexpr char kDmToken[] = "fake-dm-token";
 constexpr char kInvalidDmToken[] = "INVALID_DM_TOKEN";
+constexpr char kFakeCustomerId[] = "fake_obfuscated_customer_id";
 
 std::string GetSerializedSignedChallenge(bool use_dev = false) {
   std::string serialized_signed_challenge;
@@ -123,7 +125,15 @@
     mock_key_manager_ = std::make_unique<test::MockDeviceTrustKeyManager>();
 
     attestation_service_ = std::make_unique<DesktopAttestationService>(
-        &fake_dm_token_storage_, mock_key_manager_.get());
+        &fake_dm_token_storage_, mock_key_manager_.get(),
+        &mock_browser_cloud_policy_store_);
+  }
+
+  void SetFakeBrowserPolicyData() {
+    auto policy_data = std::make_unique<enterprise_management::PolicyData>();
+    policy_data->set_obfuscated_customer_id(kFakeCustomerId);
+    mock_browser_cloud_policy_store_.set_policy_data_for_testing(
+        std::move(policy_data));
   }
 
   void SetupPubkeyExport(bool can_export_pubkey = true) {
@@ -186,12 +196,14 @@
   test::ScopedKeyPersistenceDelegateFactory persistence_delegate_factory_;
   std::unique_ptr<test::MockDeviceTrustKeyManager> mock_key_manager_;
   policy::FakeBrowserDMTokenStorage fake_dm_token_storage_;
+  policy::MockCloudPolicyStore mock_browser_cloud_policy_store_;
 };
 
 TEST_F(DesktopAttestationServiceTest, BuildChallengeResponseDev_Success) {
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kUseVaDevKeys, "");
 
+  SetFakeBrowserPolicyData();
   SetupPubkeyExport();
   SetupSignature();
 
@@ -204,11 +216,10 @@
 }
 
 TEST_F(DesktopAttestationServiceTest, BuildChallengeResponseProd_Success) {
+  SetFakeBrowserPolicyData();
   SetupPubkeyExport();
   SetupSignature();
 
-  // TODO(crbug.com/1208881): Add signals and validate they effectively get
-  // added to the signed data.
   base::test::TestFuture<const AttestationResponse&> future;
   attestation_service_->BuildChallengeResponseForVAChallenge(
       GetSerializedSignedChallenge(/* use_dev= */ false), CreateSignals(),
@@ -253,6 +264,7 @@
 
 TEST_F(DesktopAttestationServiceTest,
        BuildChallengeResponse_FailedPublicKeyExport) {
+  SetFakeBrowserPolicyData();
   SetupPubkeyExport(/*can_export_pubkey=*/false);
   SetupSignature();
 
@@ -297,6 +309,7 @@
 }
 
 TEST_F(DesktopAttestationServiceTest, BuildChallengeResponse_NoSignature) {
+  SetFakeBrowserPolicyData();
   SetupPubkeyExport();
   SetupSignature(/*can_sign=*/false);
 
@@ -308,4 +321,17 @@
   VerifyAttestationResponse(future.Get(), /*has_signature=*/false);
 }
 
+TEST_F(DesktopAttestationServiceTest,
+       BuildChallengeResponse_NoBrowserCustomerId) {
+  SetupPubkeyExport();
+  SetupSignature();
+
+  base::test::TestFuture<const AttestationResponse&> future;
+  attestation_service_->BuildChallengeResponseForVAChallenge(
+      GetSerializedSignedChallenge(/* use_dev= */ false), CreateSignals(),
+      std::set<enterprise_connectors::DTCPolicyLevel>(), future.GetCallback());
+
+  VerifyAttestationResponse(future.Get());
+}
+
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
index bd58f08..34efa80 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
@@ -14,21 +14,6 @@
 
 namespace enterprise_connectors {
 
-namespace {
-
-const base::Value::List* GetPolicyUrlPatterns(PrefService* prefs) {
-  if (!prefs->IsManagedPreference(kContextAwareAccessSignalsAllowlistPref))
-    return nullptr;
-  return &prefs->GetList(kContextAwareAccessSignalsAllowlistPref);
-}
-
-bool ConnectorPolicyHasValues(PrefService* profile_prefs) {
-  const auto* list = GetPolicyUrlPatterns(profile_prefs);
-  return list && !list->empty();
-}
-
-}  // namespace
-
 DeviceTrustConnectorService::DeviceTrustConnectorService(
     PrefService* profile_prefs)
     : profile_prefs_(profile_prefs) {
@@ -38,39 +23,60 @@
     return;
   }
 
-  if (!pref_observer_.IsEmpty()) {
-    return;
-  }
-
   pref_observer_.Init(profile_prefs_);
-  pref_observer_.Add(
-      kContextAwareAccessSignalsAllowlistPref,
-      base::BindRepeating(&DeviceTrustConnectorService::OnPolicyUpdated,
-                          weak_factory_.GetWeakPtr()));
+  if (IsUserInlineFlowFeatureEnabled()) {
+    policy_details_map_.emplace(
+        DTCPolicyLevel::kUser,
+        DTCPolicyDetails(kUserContextAwareAccessSignalsAllowlistPref));
+    policy_details_map_.emplace(
+        DTCPolicyLevel::kBrowser,
+        DTCPolicyDetails(kBrowserContextAwareAccessSignalsAllowlistPref));
 
-  // Call once to initialize the watcher with the current pref's values.
-  OnPolicyUpdated();
+    for (auto const& policy_details : policy_details_map_) {
+      pref_observer_.Add(
+          policy_details.second.pref,
+          base::BindRepeating(&DeviceTrustConnectorService::OnPolicyUpdated,
+                              weak_factory_.GetWeakPtr(),
+                              /*DTCPolicyLevel = */ policy_details.first,
+                              /*pref = */ policy_details.second.pref));
+
+      // Call once to initialize the watcher with the current pref's values.
+      OnPolicyUpdated(/*DTCPolicyLevel = */ policy_details.first,
+                      /*pref = */ policy_details.second.pref);
+    }
+  } else {
+    pref_observer_.Add(
+        kContextAwareAccessSignalsAllowlistPref,
+        base::BindRepeating(
+            &DeviceTrustConnectorService::OnOriginalPolicyUpdated,
+            weak_factory_.GetWeakPtr()));
+
+    // Call once to initialize the watcher with the current pref's values.
+    OnOriginalPolicyUpdated();
+  }
 }
-
 DeviceTrustConnectorService::~DeviceTrustConnectorService() = default;
 
 bool DeviceTrustConnectorService::IsConnectorEnabled() const {
-  if (!IsDeviceTrustConnectorFeatureEnabled() || !profile_prefs_) {
-    return false;
-  }
-  return ConnectorPolicyHasValues(profile_prefs_);
+  return !GetEnabledInlinePolicyLevels().empty();
 }
 
 const std::set<DTCPolicyLevel> DeviceTrustConnectorService::Watches(
     const GURL& url) const {
   std::set<DTCPolicyLevel> levels;
 
-  if (matcher_ && !matcher_->MatchURL(url).empty()) {
-    // TODO(b/279063343): This is temporary, later this service should insert
-    // the correct policy levels based on the scope of the policy matchers(i.e
-    // browser, user).
-    levels.insert(DTCPolicyLevel::kBrowser);
-    levels.insert(DTCPolicyLevel::kUser);
+  if (IsUserInlineFlowFeatureEnabled()) {
+    for (auto const& policy_details : policy_details_map_) {
+      if (policy_details.second.matcher &&
+          !policy_details.second.matcher->MatchURL(url).empty()) {
+        levels.insert(policy_details.first);
+      }
+    }
+  } else {
+    if (matcher_ && !matcher_->MatchURL(url).empty()) {
+      levels.insert(DTCPolicyLevel::kBrowser);
+      levels.insert(DTCPolicyLevel::kUser);
+    }
   }
 
   return levels;
@@ -80,16 +86,86 @@
     std::unique_ptr<PolicyObserver> observer) {
   observers_.push_back(std::move(observer));
 
-  // TODO(b/277902094): Ideally the matchers should not be reinitialized when
-  // adding an observer, the current state (or prefs having values) should be
-  // used to trigger enabled/disabled updates.
-  OnPolicyUpdated();
+  if (IsUserInlineFlowFeatureEnabled()) {
+    for (auto const& policy_details : policy_details_map_) {
+      if (policy_details.second.enabled) {
+        OnInlinePolicyEnabled(/*DTCPolicyLevel = */ policy_details.first);
+      } else {
+        OnInlinePolicyDisabled(/*DTCPolicyLevel = */ policy_details.first);
+      }
+    }
+  } else {
+    OnOriginalPolicyUpdated();
+  }
 }
 
-void DeviceTrustConnectorService::OnPolicyUpdated() {
+const std::set<DTCPolicyLevel>
+DeviceTrustConnectorService::GetEnabledInlinePolicyLevels() const {
+  std::set<DTCPolicyLevel> levels;
+
+  if (!IsDeviceTrustConnectorFeatureEnabled() || !profile_prefs_) {
+    return levels;
+  }
+
+  if (IsUserInlineFlowFeatureEnabled()) {
+    for (auto const& policy_details : policy_details_map_) {
+      if (policy_details.second.enabled) {
+        levels.insert(policy_details.first);
+      }
+    }
+  } else {
+    const base::Value::List* url_patterns =
+        GetPolicyUrlPatterns(kContextAwareAccessSignalsAllowlistPref);
+    if (url_patterns && !url_patterns->empty()) {
+      levels.insert(DTCPolicyLevel::kUser);
+      levels.insert(DTCPolicyLevel::kBrowser);
+    }
+  }
+
+  return levels;
+}
+
+DeviceTrustConnectorService::DTCPolicyDetails::DTCPolicyDetails(
+    const std::string& pref)
+    : enabled(false),
+      pref(pref),
+      matcher(std::make_unique<url_matcher::URLMatcher>()) {}
+
+DeviceTrustConnectorService::DTCPolicyDetails::DTCPolicyDetails(
+    DTCPolicyDetails&& other) = default;
+
+DeviceTrustConnectorService::DTCPolicyDetails&
+
+DeviceTrustConnectorService::DTCPolicyDetails::operator=(
+    DeviceTrustConnectorService::DTCPolicyDetails&& other) = default;
+
+DeviceTrustConnectorService::DTCPolicyDetails::~DTCPolicyDetails() = default;
+
+void DeviceTrustConnectorService::OnPolicyUpdated(const DTCPolicyLevel& level,
+                                                  const std::string& pref) {
+  CHECK(IsUserInlineFlowFeatureEnabled());
+
+  const base::Value::List* url_patterns = GetPolicyUrlPatterns(pref);
+  auto& policy_details = policy_details_map_.at(level);
+  // Reset the matcher and update the policy details.
+  policy_details.matcher = std::make_unique<url_matcher::URLMatcher>();
+  policy_details.enabled = url_patterns && !url_patterns->empty();
+
+  if (policy_details.enabled) {
+    // Add the new endpoints to the conditions.
+    url_matcher::util::AddAllowFilters(policy_details.matcher.get(),
+                                       *url_patterns);
+    OnInlinePolicyEnabled(level);
+  } else {
+    OnInlinePolicyDisabled(level);
+  }
+}
+
+void DeviceTrustConnectorService::OnOriginalPolicyUpdated() {
   DCHECK(IsDeviceTrustConnectorFeatureEnabled());
 
-  const base::Value::List* url_patterns = GetPolicyUrlPatterns(profile_prefs_);
+  const base::Value::List* url_patterns =
+      GetPolicyUrlPatterns(kContextAwareAccessSignalsAllowlistPref);
 
   if (!matcher_ || !matcher_->IsEmpty()) {
     // Reset the matcher.
@@ -119,4 +195,12 @@
   }
 }
 
+const base::Value::List* DeviceTrustConnectorService::GetPolicyUrlPatterns(
+    const std::string& pref) const {
+  if (!profile_prefs_->IsManagedPreference(pref)) {
+    return nullptr;
+  }
+  return &profile_prefs_->GetList(pref);
+}
+
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h
index 69ab70d..b67198d 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h
@@ -9,7 +9,9 @@
 #include <set>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "base/memory/raw_ptr.h"
+#include "base/values.h"
 #include "chrome/browser/enterprise/connectors/device_trust/common/common_types.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
@@ -57,19 +59,52 @@
   // Adds `observer` to the list of owned policy observers.
   void AddObserver(std::unique_ptr<PolicyObserver> observer);
 
+  // Returns the policy levels the service is enabled for.
+  const std::set<DTCPolicyLevel> GetEnabledInlinePolicyLevels() const;
+
  private:
-  // Called when the ContextAwareAccessSignalsAllowlist policy value changes in
-  // Prefs.
-  void OnPolicyUpdated();
+  // Contains details relating to a policy.
+  struct DTCPolicyDetails {
+    explicit DTCPolicyDetails(const std::string& pref);
+    DTCPolicyDetails(DTCPolicyDetails&& other);
+    DTCPolicyDetails& operator=(DTCPolicyDetails&&);
+    ~DTCPolicyDetails();
+
+    // Whether the policy is enabled or not.
+    bool enabled;
+
+    // The name of the pref that contains the DTC policy values.
+    std::string pref;
+
+    // The URL matcher for the current policy.
+    std::unique_ptr<url_matcher::URLMatcher> matcher;
+  };
+
+  // Called when the DTC policies values change in Prefs for the
+  // UserContextAwareAccessSignalsAllowlist policy and the
+  // BrowserContextAwareAccessSignalsAllowlist policy. The `pref` is the pref
+  // value that changed, and `level` is the policy level of the policy that was
+  // updated.
+  void OnPolicyUpdated(const DTCPolicyLevel& level, const std::string& pref);
+
+  // Called when the DTC policies values change in Prefs for the
+  // ContextAwareAccessSignalsAllowlist policy.
+  void OnOriginalPolicyUpdated();
 
   // Functions used to propagate an update to all observers.
   void OnInlinePolicyEnabled(DTCPolicyLevel level);
   void OnInlinePolicyDisabled(DTCPolicyLevel level);
 
+  // Gets a list of URLs from the specified `pref`.
+  const base::Value::List* GetPolicyUrlPatterns(const std::string& pref) const;
+
   PrefChangeRegistrar pref_observer_;
 
   raw_ptr<PrefService> profile_prefs_;
 
+  // Maps the policy details per policy level.
+  base::flat_map<DTCPolicyLevel, DTCPolicyDetails> policy_details_map_;
+
   // The URL matcher created from the ContextAwareAccessSignalsAllowlist policy.
   std::unique_ptr<url_matcher::URLMatcher> matcher_;
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
index 34848daf..498dda9 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h"
 
+#include <utility>
+
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
@@ -20,10 +22,12 @@
 constexpr char kExampleDomain1[] = "example1.com";
 constexpr char kExampleDomain2[] = "example2.com";
 constexpr char kExampleDomain3[] = "example3.com";
+constexpr char kExampleDomain4[] = "example4.com";
 
 constexpr char kExampleUrl1[] = "https://example1.com/somepath";
 constexpr char kExampleUrl2[] = "https://example2.com/some2path";
 constexpr char kExampleUrl3[] = "https://example3.com/some3path";
+constexpr char kExampleUrl4[] = "https://example4.com/some4path";
 
 base::Value::List GetOrigins() {
   base::Value::List origins;
@@ -40,6 +44,19 @@
   return more_origins;
 }
 
+base::Value::List GetDifferentOrigins() {
+  base::Value::List more_origins;
+  more_origins.Append(kExampleDomain3);
+  more_origins.Append(kExampleDomain4);
+  return more_origins;
+}
+
+void SetPolicy(TestingPrefServiceSimple* prefs,
+               const std::string& pref_name,
+               base::Value::List list = base::Value::List()) {
+  prefs->SetManagedPref(pref_name, std::move(list));
+}
+
 class MockPolicyObserver : public DeviceTrustConnectorService::PolicyObserver {
  public:
   MockPolicyObserver() {}
@@ -55,45 +72,138 @@
 class DeviceTrustConnectorServiceTest : public testing::Test {
  protected:
   DeviceTrustConnectorServiceTest(bool feature_enabled = true,
-                                  bool has_policy_value = true) {
+                                  bool has_policy_value = true)
+      : feature_enabled_(feature_enabled), has_policy_value_(has_policy_value) {
     RegisterDeviceTrustConnectorProfilePrefs(prefs_.registry());
-    feature_list_.InitWithFeatureState(kDeviceTrustConnectorEnabled,
-                                       feature_enabled);
+
     levels_.insert(DTCPolicyLevel::kBrowser);
     levels_.insert(DTCPolicyLevel::kUser);
-
-    if (has_policy_value) {
-      EnableServicePolicy();
-    } else {
-      DisableServicePolicy();
-    }
-  }
-
-  void EnableServicePolicy() {
-    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
-                          base::Value(GetOrigins()));
-  }
-
-  void UpdateServicePolicy() {
-    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
-                          base::Value(GetMoreOrigins()));
-  }
-
-  void DisableServicePolicy() {
-    prefs_.SetManagedPref(kContextAwareAccessSignalsAllowlistPref,
-                          base::Value(base::Value::List()));
   }
 
   std::unique_ptr<DeviceTrustConnectorService> CreateService() {
     return std::make_unique<DeviceTrustConnectorService>(&prefs_);
   }
 
+  void InitializeFeatureFlags(bool user_dtc_feature_enabled) {
+    if (feature_enabled_ && user_dtc_feature_enabled) {
+      feature_list_.InitWithFeatures(
+          /*enabled_features=*/{kDeviceTrustConnectorEnabled,
+                                kUserDTCInlineFlowEnabled},
+          /*disabled_features=*/{});
+    } else if (feature_enabled_) {
+      feature_list_.InitWithFeatures(
+          /*`enabled_features=*/{kDeviceTrustConnectorEnabled},
+          /*disabled_features=*/{kUserDTCInlineFlowEnabled});
+    } else {
+      feature_list_.InitWithFeatures(
+          /*enabled_features=*/{}, /*disabled_features=*/{
+              kDeviceTrustConnectorEnabled, kUserDTCInlineFlowEnabled});
+    }
+  }
+
+  void InitializePrefs(const std::string& pref,
+                       bool user_dtc_feature_enabled = false) {
+    InitializeFeatureFlags(user_dtc_feature_enabled);
+    if (has_policy_value_) {
+      SetPolicy(&prefs_, pref, GetOrigins());
+    }
+  }
+
+  void TestMatchesUpdateFlow(const std::string& pref,
+                             const std::set<DTCPolicyLevel> level) {
+    auto service = CreateService();
+
+    GURL url1(kExampleUrl1);
+    GURL url2(kExampleUrl2);
+    GURL url3(kExampleUrl3);
+
+    EXPECT_EQ(level, service->Watches(url1));
+    EXPECT_EQ(level, service->Watches(url2));
+
+    EXPECT_EQ(std::set<DTCPolicyLevel>(), service->Watches(url3));
+
+    SetPolicy(&prefs_, pref, GetMoreOrigins());
+
+    EXPECT_EQ(level, service->Watches(url1));
+    EXPECT_EQ(level, service->Watches(url2));
+    EXPECT_EQ(level, service->Watches(url3));
+    EXPECT_EQ(level, service->GetEnabledInlinePolicyLevels());
+  }
+
+  void TestPolicyObserverFlow(
+      const std::string& pref,
+      std::set<DTCPolicyLevel> levels,
+      std::set<DTCPolicyLevel> disabled_levels = std::set<DTCPolicyLevel>()) {
+    auto service = CreateService();
+    auto observer = std::make_unique<testing::StrictMock<MockPolicyObserver>>();
+    auto* observer_ptr = observer.get();
+
+    // The policy currently has values and adding the observer will get
+    // it invoked with an "enabled" notification.
+    for (const auto& level : levels) {
+      EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(level));
+    }
+
+    for (const auto& level : disabled_levels) {
+      EXPECT_CALL(*observer_ptr, OnInlinePolicyDisabled(level));
+    }
+    service->AddObserver(std::move(observer));
+
+    // Updating the policy to new values will trigger an "enabled"
+    for (const auto& level : levels) {
+      EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(level));
+    }
+    SetPolicy(&prefs_, pref, GetMoreOrigins());
+
+    // Disabling the policy will trigger a "disabled" update.
+    for (const auto& level : levels) {
+      EXPECT_CALL(*observer_ptr, OnInlinePolicyDisabled(level));
+    }
+    SetPolicy(&prefs_, pref);
+  }
+
   base::test::ScopedFeatureList feature_list_;
   TestingPrefServiceSimple prefs_;
   std::set<DTCPolicyLevel> levels_;
+  bool feature_enabled_ = true;
+  bool has_policy_value_ = true;
 };
 
-TEST_F(DeviceTrustConnectorServiceTest, Matches_Update) {
+// Tests that the DTC policy levels set is enabled at the correct levels for the
+// ContextAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest, OriginalPolicy_Matches_Update) {
+  InitializePrefs(kContextAwareAccessSignalsAllowlistPref);
+  TestMatchesUpdateFlow(kContextAwareAccessSignalsAllowlistPref, levels_);
+}
+
+// Tests that the DTC policy levels set is enabled at the correct levels for the
+// UserContextAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest, UserPolicy_Matches_Update) {
+  InitializePrefs(kUserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestMatchesUpdateFlow(kUserContextAwareAccessSignalsAllowlistPref,
+                        std::set<DTCPolicyLevel>({DTCPolicyLevel::kUser}));
+}
+
+// Tests that the DTC policy levels set is enabled at the correct levels for the
+// BrowserContextAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest, BrowserPolicy_Matches_Update) {
+  InitializePrefs(kBrowserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestMatchesUpdateFlow(kBrowserContextAwareAccessSignalsAllowlistPref,
+                        std::set<DTCPolicyLevel>({DTCPolicyLevel::kBrowser}));
+}
+
+// Tests that the DTC policy levels set is enabled at the correct levels when
+// both the UserContextAwareAccessSignalsAllowlist and the
+// BrowserContextAwareAccessSignalsAllowlist policy are enabled at the same time
+// with the same policy values.
+TEST_F(DeviceTrustConnectorServiceTest,
+       UserAndBrowserPolicy_SameURLsMatches_Update) {
+  InitializePrefs(kBrowserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  SetPolicy(&prefs_, kUserContextAwareAccessSignalsAllowlistPref, GetOrigins());
+
   auto service = CreateService();
 
   GURL url1(kExampleUrl1);
@@ -102,36 +212,89 @@
 
   EXPECT_EQ(levels_, service->Watches(url1));
   EXPECT_EQ(levels_, service->Watches(url2));
-
   EXPECT_EQ(std::set<DTCPolicyLevel>(), service->Watches(url3));
 
-  UpdateServicePolicy();
+  // Updating the URLs.
+  SetPolicy(&prefs_, kBrowserContextAwareAccessSignalsAllowlistPref,
+            GetMoreOrigins());
+  SetPolicy(&prefs_, kUserContextAwareAccessSignalsAllowlistPref,
+            GetMoreOrigins());
 
   EXPECT_EQ(levels_, service->Watches(url1));
   EXPECT_EQ(levels_, service->Watches(url2));
   EXPECT_EQ(levels_, service->Watches(url3));
+  EXPECT_EQ(levels_, service->GetEnabledInlinePolicyLevels());
 }
 
-TEST_F(DeviceTrustConnectorServiceTest, PolicyObserver_Notified) {
+// Tests that the DTC policy levels set is enabled at the correct levels when
+// both the UserContextAwareAccessSignalsAllowlist and the
+// BrowserContextAwareAccessSignalsAllowlist policy are enabled at the same time
+// with different policy values.
+TEST_F(DeviceTrustConnectorServiceTest,
+       UserAndBrowserPolicy_DifferentURLsMatches_Update) {
+  auto user_policy_level = std::set<DTCPolicyLevel>({DTCPolicyLevel::kUser});
+  auto browser_policy_level =
+      std::set<DTCPolicyLevel>({DTCPolicyLevel::kBrowser});
+
+  InitializePrefs(kBrowserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  SetPolicy(&prefs_, kUserContextAwareAccessSignalsAllowlistPref,
+            GetDifferentOrigins());
+
   auto service = CreateService();
-  auto observer = std::make_unique<testing::StrictMock<MockPolicyObserver>>();
-  auto* observer_ptr = observer.get();
 
-  // The policy currently has values and adding the observer will get it invoked
-  // with an "enabled" notification.
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(DTCPolicyLevel::kBrowser));
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(DTCPolicyLevel::kUser));
-  service->AddObserver(std::move(observer));
+  GURL url1(kExampleUrl1);
+  GURL url2(kExampleUrl2);
+  GURL url3(kExampleUrl3);
+  GURL url4(kExampleUrl4);
 
-  // Updating the policy to new values will trigger an "enabled"
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(DTCPolicyLevel::kBrowser));
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyEnabled(DTCPolicyLevel::kUser));
-  UpdateServicePolicy();
+  EXPECT_EQ(browser_policy_level, service->Watches(url1));
+  EXPECT_EQ(browser_policy_level, service->Watches(url2));
+  EXPECT_EQ(user_policy_level, service->Watches(url3));
+  EXPECT_EQ(user_policy_level, service->Watches(url4));
 
-  // Disabling the policy will trigger a "disabled" update.
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyDisabled(DTCPolicyLevel::kBrowser));
-  EXPECT_CALL(*observer_ptr, OnInlinePolicyDisabled(DTCPolicyLevel::kUser));
-  DisableServicePolicy();
+  // Updating the URLs.
+  SetPolicy(&prefs_, kBrowserContextAwareAccessSignalsAllowlistPref,
+            GetDifferentOrigins());
+  SetPolicy(&prefs_, kUserContextAwareAccessSignalsAllowlistPref, GetOrigins());
+
+  EXPECT_EQ(user_policy_level, service->Watches(url1));
+  EXPECT_EQ(user_policy_level, service->Watches(url2));
+  EXPECT_EQ(browser_policy_level, service->Watches(url3));
+  EXPECT_EQ(browser_policy_level, service->Watches(url4));
+  EXPECT_EQ(levels_, service->GetEnabledInlinePolicyLevels());
+}
+
+// Tests that the policy observer behaves as intended for the
+// ContextAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest,
+       OriginalPolicy_PolicyObserver_Notified) {
+  InitializePrefs(kContextAwareAccessSignalsAllowlistPref);
+  TestPolicyObserverFlow(kContextAwareAccessSignalsAllowlistPref,
+                         /*enabled_levels= */ levels_);
+}
+
+// Tests that the policy observer behaves as intended for the
+// UserContextAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest, UserPolicy_PolicyObserver_Notified) {
+  InitializePrefs(kUserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestPolicyObserverFlow(
+      kUserContextAwareAccessSignalsAllowlistPref,
+      /*levels= */ std::set<DTCPolicyLevel>({DTCPolicyLevel::kUser}),
+      /*disabled_levels= */
+      std::set<DTCPolicyLevel>({DTCPolicyLevel::kBrowser}));
+}
+
+// Tests that the policy observer behaves as intended for the
+// BrowserAwareAccessSignalsAllowlist policy.
+TEST_F(DeviceTrustConnectorServiceTest, BrowserPolicy_PolicyObserver_Notified) {
+  InitializePrefs(kBrowserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestPolicyObserverFlow(
+      kBrowserContextAwareAccessSignalsAllowlistPref,
+      /*levels= */ std::set<DTCPolicyLevel>({DTCPolicyLevel::kBrowser}),
+      /*disabled_levels= */ std::set<DTCPolicyLevel>({DTCPolicyLevel::kUser}));
 }
 
 class DeviceTrustConnectorServiceFlagTest
@@ -148,21 +311,48 @@
 
   bool is_flag_enabled() { return std::get<0>(GetParam()); }
   bool is_policy_enabled() { return std::get<1>(GetParam()); }
+
+  void TestConnectorEnabledFlow(const std::string& pref) {
+    auto service = CreateService();
+    EXPECT_EQ(is_attestation_flow_enabled(), service->IsConnectorEnabled());
+
+    if (!is_flag_enabled()) {
+      return;
+    }
+
+    SetPolicy(&prefs_, pref, GetOrigins());
+
+    EXPECT_TRUE(service->IsConnectorEnabled());
+  }
 };
 
 // Parameterized test covering a matrix of enabled/disabled states depending on
-// both the feature flag and the policy values.
-TEST_P(DeviceTrustConnectorServiceFlagTest, IsConnectorEnabled_Update) {
-  auto service = CreateService();
-  EXPECT_EQ(is_attestation_flow_enabled(), service->IsConnectorEnabled());
+// both the feature flag and the policy values for the
+// ContextAwareAccessSignalsAllowlist policy.
+TEST_P(DeviceTrustConnectorServiceFlagTest,
+       OriginalPolicy_IsConnectorEnabled_Update) {
+  InitializePrefs(kContextAwareAccessSignalsAllowlistPref);
+  TestConnectorEnabledFlow(kContextAwareAccessSignalsAllowlistPref);
+}
 
-  if (!is_flag_enabled()) {
-    return;
-  }
+// Parameterized test covering a matrix of enabled/disabled states depending on
+// both the feature flag and the policy values for the
+// UserContextAwareAccessSignalsAllowlist policy.
+TEST_P(DeviceTrustConnectorServiceFlagTest,
+       UserPolicy_IsConnectorEnabled_Update) {
+  InitializePrefs(kUserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestConnectorEnabledFlow(kUserContextAwareAccessSignalsAllowlistPref);
+}
 
-  UpdateServicePolicy();
-
-  EXPECT_TRUE(service->IsConnectorEnabled());
+// Parameterized test covering a matrix of enabled/disabled states depending on
+// both the feature flag and the policy values for the
+// BrowserContextAwareAccessSignalsAllowlist policy.
+TEST_P(DeviceTrustConnectorServiceFlagTest,
+       BrowserPolicy_IsConnectorEnabled_Update) {
+  InitializePrefs(kBrowserContextAwareAccessSignalsAllowlistPref,
+                  /*user_dtc_feature_enabled= */ true);
+  TestConnectorEnabledFlow(kBrowserContextAwareAccessSignalsAllowlistPref);
 }
 
 INSTANTIATE_TEST_SUITE_P(,
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
index 6856cd9..78569da7 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
@@ -29,6 +29,9 @@
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h"
 #include "components/enterprise/browser/device_trust/device_trust_key_manager.h"
+#include "components/policy/core/common/cloud/cloud_policy_store.h"
+#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
+#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h"
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -101,14 +104,20 @@
       std::make_unique<AshAttestationService>(profile);
 #else
   DeviceTrustKeyManager* key_manager = nullptr;
+  policy::CloudPolicyStore* browser_cloud_policy_store = nullptr;
   auto* browser_policy_connector =
       g_browser_process->browser_policy_connector();
   if (browser_policy_connector) {
     auto* cbcm_controller =
         browser_policy_connector->chrome_browser_cloud_management_controller();
+    auto* machine_policy_manager =
+        browser_policy_connector->machine_level_user_cloud_policy_manager();
     if (cbcm_controller) {
       key_manager = cbcm_controller->GetDeviceTrustKeyManager();
     }
+    if (machine_policy_manager) {
+      browser_cloud_policy_store = machine_policy_manager->store();
+    }
   }
 
   if (!key_manager) {
@@ -117,7 +126,8 @@
 
   std::unique_ptr<AttestationService> attestation_service =
       std::make_unique<DesktopAttestationService>(
-          policy::BrowserDMTokenStorage::Get(), key_manager);
+          policy::BrowserDMTokenStorage::Get(), key_manager,
+          browser_cloud_policy_store);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   auto signals_service = CreateSignalsService(profile);
diff --git a/chrome/browser/enterprise/connectors/device_trust/prefs.cc b/chrome/browser/enterprise/connectors/device_trust/prefs.cc
index 16c0ba3..609531c5 100644
--- a/chrome/browser/enterprise/connectors/device_trust/prefs.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/prefs.cc
@@ -9,8 +9,16 @@
 const char kContextAwareAccessSignalsAllowlistPref[] =
     "enterprise_connectors.device_trust.origins";
 
+const char kUserContextAwareAccessSignalsAllowlistPref[] =
+    "enterprise_connectors.device_trust_user.origins";
+
+const char kBrowserContextAwareAccessSignalsAllowlistPref[] =
+    "enterprise_connectors.device_trust_browser.origins";
+
 void RegisterDeviceTrustConnectorProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterListPref(kContextAwareAccessSignalsAllowlistPref);
+  registry->RegisterListPref(kUserContextAwareAccessSignalsAllowlistPref);
+  registry->RegisterListPref(kBrowserContextAwareAccessSignalsAllowlistPref);
 }
 
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/prefs.h b/chrome/browser/enterprise/connectors/device_trust/prefs.h
index 03306d2..e23e08e 100644
--- a/chrome/browser/enterprise/connectors/device_trust/prefs.h
+++ b/chrome/browser/enterprise/connectors/device_trust/prefs.h
@@ -11,8 +11,18 @@
 namespace enterprise_connectors {
 
 // Pref that maps to the "ContextAwareAccessSignalsAllowlistPref" policy.
+// TODO(b/279840937): Clean up the "ContextAwareAccessSignalsAllowlistPref"
+// policy and references of this pref.
 extern const char kContextAwareAccessSignalsAllowlistPref[];
 
+// TODO(b/279077254): Pref that maps to the
+// "UserContextAwareAccessSignalsAllowlistPref" policy.
+extern const char kUserContextAwareAccessSignalsAllowlistPref[];
+
+// TODO(b/279077254): Pref that maps to the
+// "BrowserContextAwareAccessSignalsAllowlistPref" policy.
+extern const char kBrowserContextAwareAccessSignalsAllowlistPref[];
+
 // Registers the device trust connectors profile preferences.
 void RegisterDeviceTrustConnectorProfilePrefs(PrefRegistrySimple* registry);
 
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
index c22a12f..c6f7430 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -109,8 +109,9 @@
     return nullptr;
   }
   const BookmarkNode* parent = bookmarks::GetBookmarkNodeByID(model, parent_id);
-  if (!CanBeModified(parent, error))
+  if (!CanBeModified(parent, error) || !parent->is_folder()) {
     return nullptr;
+  }
 
   size_t index;
   if (!details.index) {  // Optional (defaults to end).
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api_unittest.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api_unittest.cc
index 2d39d6f..cfea99b 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api_unittest.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api_unittest.cc
@@ -33,29 +33,50 @@
     model_ = BookmarkModelFactory::GetForBrowserContext(profile());
     bookmarks::test::WaitForBookmarkModelToLoad(model_);
 
-    const bookmarks::BookmarkNode* node =
+    const bookmarks::BookmarkNode* folder_node =
         model_->AddFolder(model_->other_node(), 0, u"Empty folder");
-    node_id_ = base::NumberToString(node->id());
+    const bookmarks::BookmarkNode* url_node =
+        model_->AddURL(model_->other_node(), 0, u"URL", url_);
+    folder_node_id_ = base::NumberToString(folder_node->id());
+    url_node_id_ = base::NumberToString(url_node->id());
   }
 
-  std::string node_id() const { return node_id_; }
+  raw_ptr<bookmarks::BookmarkModel> model() const { return model_; }
+  std::string folder_node_id() const { return folder_node_id_; }
+  std::string url_node_id() const { return url_node_id_; }
+  const GURL url() const { return url_; }
 
  private:
   raw_ptr<bookmarks::BookmarkModel> model_ = nullptr;
-  std::string node_id_;
+  std::string folder_node_id_;
+  std::string url_node_id_;
+  const GURL url_ = GURL("https://example.org");
 };
 
 // Tests that running updating a bookmark folder's url does not succeed.
 // Regression test for https://crbug.com/818395.
 TEST_F(BookmarksApiUnittest, Update) {
   auto update_function = base::MakeRefCounted<BookmarksUpdateFunction>();
-  ASSERT_EQ(
-      R"(Can't set URL of a bookmark folder.)",
-      api_test_utils::RunFunctionAndReturnError(
-          update_function.get(),
-          base::StringPrintf(R"(["%s", {"url": "https://example.com"}])",
-                             node_id().c_str()),
-          profile()));
+  ASSERT_EQ(R"(Can't set URL of a bookmark folder.)",
+            api_test_utils::RunFunctionAndReturnError(
+                update_function.get(),
+                base::StringPrintf(R"(["%s", {"url": "https://example.com"}])",
+                                   folder_node_id().c_str()),
+                profile()));
+}
+
+// Tests that attempting to creating a bookmark with a non-folder parent does
+// not add the bookmark to that parent.
+// Regression test for https://crbug.com/1441071.
+TEST_F(BookmarksApiUnittest, Create) {
+  auto create_function = base::MakeRefCounted<BookmarksCreateFunction>();
+  api_test_utils::RunFunction(
+      create_function.get(),
+      base::StringPrintf(R"([{"parent_id": "%s"}])", url_node_id().c_str()),
+      profile());
+  const bookmarks::BookmarkNode* url_node =
+      model()->GetMostRecentlyAddedUserNodeForURL(url());
+  ASSERT_TRUE(url_node->children().empty());
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index 840d033..a61955c 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -6169,7 +6169,7 @@
 
 // Tests the behavior of an extension that registers an event listener
 // asynchronously.
-// Regression test for https://crbug.com/1397879.
+// Regression test for https://crbug.com/1397879 and https://crbug.com/1434212.
 IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, AsyncListenerRegistration) {
   ASSERT_TRUE(StartEmbeddedTestServer());
   static constexpr char kManifest[] =
@@ -6200,6 +6200,13 @@
                ['blocking']);
            chrome.test.sendMessage('registered');
          });
+         // Register an additional event properly so that the service worker
+         // still has _a_ listener registered in the process.
+         // https://crbug.com/1434212.
+         chrome.webRequest.onHeadersReceived.addListener(
+             (details) => {},
+             {urls: ['<all_urls>'], types: ['main_frame']},
+             ['blocking']);
          chrome.test.sendMessage('ready');)";
 
   // Load the extension and tell it to register the listener.
diff --git a/chrome/browser/extensions/browsertest_util.cc b/chrome/browser/extensions/browsertest_util.cc
index 3961f81..1c960eab 100644
--- a/chrome/browser/extensions/browsertest_util.cc
+++ b/chrome/browser/extensions/browsertest_util.cc
@@ -95,4 +95,21 @@
   return false;
 }
 
+BlockedActionWaiter::BlockedActionWaiter(ExtensionActionRunner* runner)
+    : runner_(runner) {
+  runner_->set_observer_for_testing(this);  // IN-TEST
+}
+
+BlockedActionWaiter::~BlockedActionWaiter() {
+  runner_->set_observer_for_testing(nullptr);  // IN-TEST
+}
+
+void BlockedActionWaiter::Wait() {
+  run_loop_.Run();
+}
+
+void BlockedActionWaiter::OnBlockedActionAdded() {
+  run_loop_.Quit();
+}
+
 }  // namespace extensions::browsertest_util
diff --git a/chrome/browser/extensions/browsertest_util.h b/chrome/browser/extensions/browsertest_util.h
index 7bfa8957..600e190 100644
--- a/chrome/browser/extensions/browsertest_util.h
+++ b/chrome/browser/extensions/browsertest_util.h
@@ -6,11 +6,17 @@
 #define CHROME_BROWSER_EXTENSIONS_BROWSERTEST_UTIL_H_
 
 #include <string>
+#include "base/run_loop.h"
+#include "chrome/browser/extensions/extension_action_runner.h"
 
 class Browser;
 class GURL;
 class Profile;
 
+namespace base {
+class RunLoop;
+}
+
 namespace content {
 class WebContents;
 }
@@ -41,6 +47,30 @@
                     const std::u16string& original_title,
                     const std::u16string& changed_title);
 
+// Can be used to wait for blocked actions (pending scripts, web requests, etc.)
+// to be noticed in tests. Blocked actions recording initiates in the renderer
+// so this helps when waiting from the browser side. This should be used on the
+// stack for proper destruction.
+class BlockedActionWaiter : public ExtensionActionRunner::TestObserver {
+ public:
+  // `runner` must outlive this object.
+  explicit BlockedActionWaiter(ExtensionActionRunner* runner);
+  BlockedActionWaiter(const BlockedActionWaiter&) = delete;
+  BlockedActionWaiter& operator=(const BlockedActionWaiter&) = delete;
+  ~BlockedActionWaiter();
+
+  // Wait for the blocked action until the observer is called with the blocked
+  // action being added.
+  void Wait();
+
+ private:
+  // ExtensionActionRunner::TestObserver:
+  void OnBlockedActionAdded() override;
+
+  const raw_ptr<ExtensionActionRunner> runner_;
+  base::RunLoop run_loop_;
+};
+
 }  // namespace browsertest_util
 }  // namespace extensions
 
diff --git a/chrome/browser/extensions/extension_action_runner_browsertest.cc b/chrome/browser/extensions/extension_action_runner_browsertest.cc
index 5836440..2595da57 100644
--- a/chrome/browser/extensions/extension_action_runner_browsertest.cc
+++ b/chrome/browser/extensions/extension_action_runner_browsertest.cc
@@ -237,29 +237,7 @@
 
   ASSERT_EQ(REQUIRES_CONSENT, requires_consent);
 
-  class BlockedActionWaiter : public ExtensionActionRunner::TestObserver {
-   public:
-    explicit BlockedActionWaiter(ExtensionActionRunner* runner)
-        : runner_(runner) {
-      runner_->set_observer_for_testing(this);
-    }
-
-    BlockedActionWaiter(const BlockedActionWaiter&) = delete;
-    BlockedActionWaiter& operator=(const BlockedActionWaiter&) = delete;
-
-    ~BlockedActionWaiter() { runner_->set_observer_for_testing(nullptr); }
-
-    void Wait() { run_loop_.Run(); }
-
-   private:
-    // ExtensionActionRunner::TestObserver:
-    void OnBlockedActionAdded() override { run_loop_.Quit(); }
-
-    raw_ptr<ExtensionActionRunner> runner_;
-    base::RunLoop run_loop_;
-  };
-
-  BlockedActionWaiter waiter(runner);
+  browsertest_util::BlockedActionWaiter waiter(runner);
   navigate();
   waiter.Wait();
   EXPECT_TRUE(runner->WantsToRun(extension));
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 12a8ceb..82597451 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -1231,11 +1231,14 @@
       disable_reasons &= (~disable_reason::DISABLE_UPDATE_REQUIRED_BY_POLICY);
     }
 
-    // Find all extensions disabled due to published-in-webstore requirement and
-    // management policy but now satisfying it.
+    // Check published-in-store status against policy requirement and update
+    // the disable reasons accordingly.
     if (management->IsAllowedByUnpublishedAvailabilityPolicy(extension.get())) {
       disable_reasons &=
           ~disable_reason::DISABLE_PUBLISHED_IN_STORE_REQUIRED_BY_POLICY;
+    } else {
+      disable_reasons |=
+          disable_reason::DISABLE_PUBLISHED_IN_STORE_REQUIRED_BY_POLICY;
     }
 
     if (!system_->management_policy()->MustRemainDisabled(extension.get(),
diff --git a/chrome/browser/extensions/site_permissions_helper.cc b/chrome/browser/extensions/site_permissions_helper.cc
index 72853a6..0149eaf31 100644
--- a/chrome/browser/extensions/site_permissions_helper.cc
+++ b/chrome/browser/extensions/site_permissions_helper.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/extensions/extension_action_runner.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/scripting_permissions_modifier.h"
+#include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "content/public/browser/web_contents.h"
@@ -153,6 +154,14 @@
   } else if (blocked_actions != BLOCKED_ACTION_NONE) {
     runner->RunBlockedActions(&extension);
   }
+
+  // Clear extension's active tab permission since it is set when granting user
+  // site permissions.
+  if (revoking_current_site_permissions) {
+    TabHelper::FromWebContents(web_contents)
+        ->active_tab_permission_granter()
+        ->ClearActiveExtensionAndNotify(extension.id());
+  }
 }
 
 bool SitePermissionsHelper::PageNeedsRefreshToRun(int blocked_actions) {
diff --git a/chrome/browser/extensions/site_permissions_helper_browsertest.cc b/chrome/browser/extensions/site_permissions_helper_browsertest.cc
index 426c1f7d..c5dfacf 100644
--- a/chrome/browser/extensions/site_permissions_helper_browsertest.cc
+++ b/chrome/browser/extensions/site_permissions_helper_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/extensions/extension_action_runner.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/scripting_permissions_modifier.h"
+#include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/test/browser_test.h"
@@ -277,4 +278,279 @@
   EXPECT_TRUE(!ContentScriptInjected() && ExtensionWantsToRun());
 }
 
+// Provides test cases with an extension that executes a script programmatically
+// on every site it visits.
+class SitePermissionsHelperExecuteSciptBrowserTest
+    : public SitePermissionsHelperBrowserTest {
+ public:
+  void SetUpOnMainThread() override {
+    ExtensionBrowserTest::SetUpOnMainThread();
+    // Loads an extension that executes a script on every page that is navigated
+    // to. Then loads a test page and confirms it is running on the page.
+    ASSERT_TRUE(embedded_test_server()->Start());
+    extension_ = LoadExtension(test_data_dir_.AppendASCII(
+        "blocked_actions/revoke_execute_script_on_click"));
+    ASSERT_TRUE(extension_);
+
+    // Navigate to a page where the extension can run.
+    original_url_ = embedded_test_server()->GetURL("/simple.html");
+    ExtensionTestMessageListener listener("injection succeeded");
+    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), original_url_));
+    ASSERT_TRUE(active_web_contents());
+    ASSERT_TRUE(content::WaitForLoadStop(active_web_contents()));
+
+    permissions_manager_ = PermissionsManager::Get(profile());
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnAllSites);
+
+    ASSERT_TRUE(listener.WaitUntilSatisfied());
+    ASSERT_TRUE(active_action_runner());
+    ASSERT_TRUE(ContentScriptInjected());
+    ASSERT_FALSE(ExtensionWantsToRun());
+
+    permissions_helper_ = std::make_unique<SitePermissionsHelper>(profile());
+    original_nav_id_ =
+        active_nav_controller().GetLastCommittedEntry()->GetUniqueID();
+  }
+};
+
+// Tests that active tab is cleared when we revoke site permissions of an
+// extension that injects a script programmatically into the page. To fix
+// crbug.com/1433399.
+IN_PROC_BROWSER_TEST_F(
+    SitePermissionsHelperExecuteSciptBrowserTest,
+    UpdateSiteAccess_RevokingSitePermission_AlsoClearsActiveTab) {
+  // We want to control refreshes manually due to timing issues with permissions
+  // being updated across browser/renderer.
+  active_action_runner()->accept_bubble_for_testing(true);
+
+  {
+    // on all sites -> on click (revokes access)
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                          UserSiteAccess::kOnClick);
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnClick);
+    ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                      active_web_contents()),
+              SitePermissionsHelper::SiteInteraction::kWithheld);
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    ASSERT_FALSE(ContentScriptInjected());
+    ASSERT_TRUE(ExtensionWantsToRun());
+  }
+
+  ExtensionTestMessageListener listener("injection succeeded");
+  // on click -> on site (grants site access and active tab permission)
+  permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                        UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+            UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                    active_web_contents()),
+            SitePermissionsHelper::SiteInteraction::kGranted);
+  ASSERT_TRUE(listener.WaitUntilSatisfied());
+  ASSERT_TRUE(ContentScriptInjected());
+  ASSERT_FALSE(ExtensionWantsToRun());
+
+  {
+    // on site -> on-click (should remove site access and active tab
+    // permissions)
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                          UserSiteAccess::kOnClick);
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnClick);
+    ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                      active_web_contents()),
+              SitePermissionsHelper::SiteInteraction::kWithheld);
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    EXPECT_FALSE(ContentScriptInjected());
+    EXPECT_TRUE(ExtensionWantsToRun());
+  }
+
+  {
+    // Confirm that unintended access isn't just waiting for a reload to allow
+    // it to run.
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    ASSERT_TRUE(ReloadPageAndWaitForLoad());
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    EXPECT_FALSE(ContentScriptInjected());
+    EXPECT_TRUE(ExtensionWantsToRun());
+  }
+}
+
+// Tests that active tab is cleared when we revoke site permissions after
+// granting active tab permissions of an extension that injects a script
+// programmatically into the page.  To fix crbug.com/1433399.
+IN_PROC_BROWSER_TEST_F(
+    SitePermissionsHelperExecuteSciptBrowserTest,
+    UpdateSiteAccess_RevokingSitePermissionAfterGrantTab_AlsoClearsActiveTab) {
+  active_action_runner()->accept_bubble_for_testing(true);
+
+  {
+    // on all sites -> on click (revokes access)
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                          UserSiteAccess::kOnClick);
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnClick);
+    ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                      active_web_contents()),
+              SitePermissionsHelper::SiteInteraction::kWithheld);
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    ASSERT_FALSE(ContentScriptInjected());
+    ASSERT_TRUE(ExtensionWantsToRun());
+  }
+
+  ExtensionTestMessageListener listener("injection succeeded");
+  // Grant active tab independently.
+  active_action_runner()->RunAction(extension_, /*grant_tab_permissions=*/true);
+  ASSERT_TRUE(listener.WaitUntilSatisfied());
+  ASSERT_TRUE(ContentScriptInjected());
+  ASSERT_FALSE(ExtensionWantsToRun());
+
+  // on click -> on site (grants site access and redundantly active tab
+  // permission)
+  permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                        UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+            UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                    active_web_contents()),
+            SitePermissionsHelper::SiteInteraction::kGranted);
+  ASSERT_TRUE(ContentScriptInjected());
+  ASSERT_FALSE(ExtensionWantsToRun());
+
+  {
+    // on site -> on-click (should remove site access and active tab
+    // permissions)
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                          UserSiteAccess::kOnClick);
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnClick);
+    ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                      active_web_contents()),
+              SitePermissionsHelper::SiteInteraction::kWithheld);
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    EXPECT_FALSE(ContentScriptInjected());
+    EXPECT_TRUE(ExtensionWantsToRun());
+  }
+
+  {
+    // Confirm that unintended access isn't just waiting for a reload to allow
+    // it to run.
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        active_action_runner());
+    ASSERT_TRUE(ReloadPageAndWaitForLoad());
+    ASSERT_TRUE(WaitForReloadToFinish());
+    blocked_action_waiter.Wait();
+    EXPECT_FALSE(ContentScriptInjected());
+    EXPECT_TRUE(ExtensionWantsToRun());
+  }
+}
+
+class SitePermissionsHelperContentScriptBrowserTest
+    : public SitePermissionsHelperBrowserTest {
+  void SetUpOnMainThread() override {
+    ExtensionBrowserTest::SetUpOnMainThread();
+    // Loads an extension that injects a content script on every page that is
+    // navigated to on document_end. Then loads a test page and confirms it is
+    // running on the page.
+    ASSERT_TRUE(embedded_test_server()->Start());
+    extension_ = LoadExtension(
+        test_data_dir_.AppendASCII("blocked_actions/content_script_at_end"));
+    ASSERT_TRUE(extension_);
+
+    // Navigate to a page where the extension can run.
+    original_url_ = embedded_test_server()->GetURL("/simple.html");
+    ExtensionTestMessageListener listener("injection succeeded");
+    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), original_url_));
+    ASSERT_TRUE(active_web_contents());
+    ASSERT_TRUE(content::WaitForLoadStop(active_web_contents()));
+
+    permissions_manager_ = PermissionsManager::Get(profile());
+    ASSERT_EQ(
+        permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+        UserSiteAccess::kOnAllSites);
+
+    ASSERT_TRUE(listener.WaitUntilSatisfied());
+    ASSERT_TRUE(active_action_runner());
+    ASSERT_TRUE(ContentScriptInjected());
+    ASSERT_FALSE(ExtensionWantsToRun());
+
+    permissions_helper_ = std::make_unique<SitePermissionsHelper>(profile());
+    original_nav_id_ =
+        active_nav_controller().GetLastCommittedEntry()->GetUniqueID();
+  }
+};
+
+// Tests that active tab is cleared when we revoke site permissions of an
+// extension that injects a content script. To fix crbug.com/1433399.
+IN_PROC_BROWSER_TEST_F(
+    SitePermissionsHelperContentScriptBrowserTest,
+    UpdateSiteAccess_RevokingSitePermission_AlsoClearsActiveTab) {
+  // We want to control refreshes manually due to timing issues with permissions
+  // being updated across browser/renderer.
+  active_action_runner()->accept_bubble_for_testing(true);
+
+  // on all sites -> on click (revokes access)
+  permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                        UserSiteAccess::kOnClick);
+  ASSERT_EQ(permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+            UserSiteAccess::kOnClick);
+  ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                    active_web_contents()),
+            SitePermissionsHelper::SiteInteraction::kWithheld);
+  ASSERT_TRUE(WaitForReloadToFinish());
+  ASSERT_FALSE(ContentScriptInjected());
+  ASSERT_TRUE(ExtensionWantsToRun());
+
+  ExtensionTestMessageListener listener("injection succeeded");
+  // on click -> on site (grants site access and active tab permission)
+  permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                        UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+            UserSiteAccess::kOnSite);
+  ASSERT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                    active_web_contents()),
+            SitePermissionsHelper::SiteInteraction::kGranted);
+  ASSERT_TRUE(listener.WaitUntilSatisfied());
+  ASSERT_TRUE(ContentScriptInjected());
+  ASSERT_FALSE(ExtensionWantsToRun());
+
+  // on site -> on-click (should remove site access and active tab permissions)
+  permissions_helper_->UpdateSiteAccess(*extension_, active_web_contents(),
+                                        UserSiteAccess::kOnClick);
+  EXPECT_EQ(permissions_manager_->GetUserSiteAccess(*extension_, original_url_),
+            UserSiteAccess::kOnClick);
+  EXPECT_EQ(permissions_helper_->GetSiteInteraction(*extension_,
+                                                    active_web_contents()),
+            SitePermissionsHelper::SiteInteraction::kWithheld);
+  ASSERT_TRUE(WaitForReloadToFinish());
+  EXPECT_FALSE(ContentScriptInjected());
+  EXPECT_TRUE(ExtensionWantsToRun());
+
+  // Confirm that unintended access isn't just waiting for a reload to allow it
+  // to run.
+  ASSERT_TRUE(ReloadPageAndWaitForLoad());
+  EXPECT_FALSE(ContentScriptInjected());
+  EXPECT_TRUE(ExtensionWantsToRun());
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/feedback/android/family_info_feedback_source.cc b/chrome/browser/feedback/android/family_info_feedback_source.cc
index b6ed76f..1810781 100644
--- a/chrome/browser/feedback/android/family_info_feedback_source.cc
+++ b/chrome/browser/feedback/android/family_info_feedback_source.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "components/supervised_user/core/browser/proto/families_common.pb.h"
 #include "content/public/browser/storage_partition.h"
@@ -70,9 +69,10 @@
 void FamilyInfoFeedbackSource::GetFamilyMembers() {
   list_family_members_fetcher_ = FetchListFamilyMembers(
       *identity_manager_, url_loader_factory_,
-      KidsManagementService::GetEndpointUrl(),
-      base::BindOnce(&FamilyInfoFeedbackSource::OnResponse,
-                     base::Unretained(this)));
+      base::BindOnce(
+          &FamilyInfoFeedbackSource::OnResponse,
+          base::Unretained(this)));  // Unretained(.) is safe because `this`
+                                     // owns `list_family_members_fetcher_`.
 }
 
 void FamilyInfoFeedbackSource::OnResponse(
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
index 1f5a10f..1d60a8d4 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -104,7 +104,7 @@
 constexpr char kOnboardingTime[] = "ONBOARDING_TIME";
 constexpr char kFreeDiskSpace[] = "FREE_DISK_SPACE";
 constexpr char kTotalDiskSpace[] = "TOTAL_DISK_SPACE";
-constexpr char kChronosHomeDirectory[] = "/home/user/chronos";
+constexpr char kChronosHomeDirectory[] = "/home/chronos/user";
 constexpr char kFailedKnowledgeFactorAttempts[] =
     "FAILED_KNOWLEDGE_FACTOR_ATTEMPTS";
 #else
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 63be201..c9aed05f 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4975,6 +4975,11 @@
     "expiry_milestone": -1
   },
   {
+    "name": "memory-saver-discarded-tab-treatment",
+    "owners": [ "chrome-performance-ui-team@google.com" ],
+    "expiry_milestone": 117
+  },
+  {
     "name": "memory-saver-savings-reporting-improvements",
     "owners": [ "chrome-performance-ui-team@google.com" ],
     "expiry_milestone": 117
@@ -6371,11 +6376,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "read-later-reminder-notification",
-    "owners": [ "wylieb" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "read-printer-capabilities-with-xps",
     "owners": [ "awscreen", "//printing/OWNERS" ],
     "expiry_milestone": 120
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index dbbcd23..bd80edc3 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4008,11 +4008,6 @@
 const char kReaderModeInCCTDescription[] =
     "Open Reader Mode in Chrome Custom Tabs.";
 
-const char kReadLaterReminderNotificationName[] =
-    "Read later reminder notification";
-const char kReadLaterReminderNotificationDescription[] =
-    "Enables read later weekly reminder notification.";
-
 const char kRecoverFromNeverSaveAndroidName[] =
     "UI to recover from never save passwords on Android";
 const char kRecoverFromNeverSaveAndroidDescription[] =
@@ -4461,6 +4456,12 @@
 extern const char kHighEfficiencyModeTimeBeforeDiscardDescription[] =
     "When set, this controls the time before memory saver discards a tab.";
 
+extern const char kHighEfficiencyDiscardedTabTreatmentName[] =
+    "Enable discarded tab treatment for Memory Saver Mode.";
+extern const char kHighEfficiencyDiscardedTabTreatmentDescription[] =
+    "When enabled, discarded tabs will have a modified favicon to indicate "
+    "that state.";
+
 extern const char kHighEfficiencySavingsReportingImprovementsName[] =
     "Enable improvements to how memory savings are reported.";
 extern const char kHighEfficiencySavingsReportingImprovementsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 7ce3cce..c65ddd9 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2337,9 +2337,6 @@
 extern const char kReaderModeInCCTName[];
 extern const char kReaderModeInCCTDescription[];
 
-extern const char kReadLaterReminderNotificationName[];
-extern const char kReadLaterReminderNotificationDescription[];
-
 extern const char kRecoverFromNeverSaveAndroidName[];
 extern const char kRecoverFromNeverSaveAndroidDescription[];
 
@@ -2553,6 +2550,9 @@
 extern const char kHighEfficiencyModeTimeBeforeDiscardName[];
 extern const char kHighEfficiencyModeTimeBeforeDiscardDescription[];
 
+extern const char kHighEfficiencyDiscardedTabTreatmentName[];
+extern const char kHighEfficiencyDiscardedTabTreatmentDescription[];
+
 extern const char kHighEfficiencySavingsReportingImprovementsName[];
 extern const char kHighEfficiencySavingsReportingImprovementsDescription[];
 
diff --git a/chrome/browser/hid/hid_status_icon.cc b/chrome/browser/hid/hid_status_icon.cc
index b048c4a..a1b321c 100644
--- a/chrome/browser/hid/hid_status_icon.cc
+++ b/chrome/browser/hid/hid_status_icon.cc
@@ -90,11 +90,21 @@
 }
 
 void HidStatusIcon::ProfileAdded(Profile* profile) {
+  if (profiles_.size() == 1) {
+    auto* profile_manager = g_browser_process->profile_manager();
+    CHECK(profile_manager);
+    profile_manager->GetProfileAttributesStorage().AddObserver(this);
+  }
   RefreshIcon();
 }
 
 void HidStatusIcon::ProfileRemoved(Profile* profile) {
   RefreshIcon();
+  if (profiles_.empty()) {
+    auto* profile_manager = g_browser_process->profile_manager();
+    CHECK(profile_manager);
+    profile_manager->GetProfileAttributesStorage().RemoveObserver(this);
+  }
 }
 
 void HidStatusIcon::NotifyConnectionCountUpdated(Profile* profile) {
@@ -217,3 +227,13 @@
   menu->AddItem(index, label);
   command_id_callbacks_.push_back(std::move(callback));
 }
+
+void HidStatusIcon::OnProfileNameChanged(
+    const base::FilePath& profile_path,
+    const std::u16string& old_profile_name) {
+  auto* profile =
+      g_browser_process->profile_manager()->GetProfileByPath(profile_path);
+  if (profiles_.contains(profile)) {
+    NotifyConnectionCountUpdated(profile);
+  }
+}
diff --git a/chrome/browser/hid/hid_status_icon.h b/chrome/browser/hid/hid_status_icon.h
index 6d1701b..15e7e03 100644
--- a/chrome/browser/hid/hid_status_icon.h
+++ b/chrome/browser/hid/hid_status_icon.h
@@ -8,12 +8,15 @@
 #include <memory>
 #include <string>
 #include <vector>
-
+#include "base/files/file_path.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/hid/hid_system_tray_icon.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/status_icons/status_icon.h"
 
 class HidStatusIcon : public HidSystemTrayIcon,
-                      public StatusIconMenuModel::Delegate {
+                      public StatusIconMenuModel::Delegate,
+                      public ProfileAttributesStorage::Observer {
  public:
   HidStatusIcon();
   HidStatusIcon(const HidStatusIcon&) = delete;
@@ -47,6 +50,10 @@
   // added/removed.
   void RefreshIcon();
 
+  // Overrides from ProfileAttributesStorage::Observer
+  void OnProfileNameChanged(const base::FilePath& profile_path,
+                            const std::u16string& old_profile_name) override;
+
   // Reference to our status icon (if any) - owned by the StatusTray.
   raw_ptr<StatusIcon, DanglingUntriaged> status_icon_ = nullptr;
 
diff --git a/chrome/browser/hid/hid_status_icon_unittest.cc b/chrome/browser/hid/hid_status_icon_unittest.cc
index c190c9e..c9ecb79 100644
--- a/chrome/browser/hid/hid_status_icon_unittest.cc
+++ b/chrome/browser/hid/hid_status_icon_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/hid/hid_status_icon.h"
+
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/hid/hid_system_tray_icon_unittest.h"
 
@@ -274,16 +276,23 @@
 
 TEST_F(HidStatusIconTest, ProfileUserName) {
   std::vector<HidSystemTrayIconTestBase::ProfileItem> profile_connection_counts;
-  std::string profile_name = base::StringPrintf("user 1");
-  auto* profile = CreateTestingProfile(profile_name);
-  auto extension = CreateExtensionWithName("Test Extension");
-  AddExtensionToProfile(profile, extension.get());
-  auto* connection_tracker =
-      HidConnectionTrackerFactory::GetForProfile(profile,
-                                                 /*create=*/true);
-  connection_tracker->IncrementConnectionCount(extension->origin());
-  profile_connection_counts.push_back(
-      {profile, {{extension->origin(), 1, extension->name()}}});
+  std::vector<std::string> profile_names;
+  std::vector<std::string> new_profile_names;
+  std::vector<base::FilePath> profile_paths;
+  for (size_t idx = 0; idx < 2; idx++) {
+    profile_names.push_back(base::StringPrintf("user%zu", idx));
+    new_profile_names.push_back(base::StringPrintf("user%zu-newname", idx));
+    auto* profile = CreateTestingProfile(profile_names.back());
+    auto extension = CreateExtensionWithName("Test Extension");
+    AddExtensionToProfile(profile, extension.get());
+    auto* connection_tracker =
+        HidConnectionTrackerFactory::GetForProfile(profile,
+                                                   /*create=*/true);
+    connection_tracker->IncrementConnectionCount(extension->origin());
+    profile_connection_counts.push_back(
+        {profile, {{extension->origin(), 1, extension->name()}}});
+    profile_paths.push_back(profile->GetPath());
+  }
   CheckIcon(profile_connection_counts);
 
   const auto* status_tray = static_cast<MockStatusTray*>(
@@ -293,7 +302,35 @@
   const auto* status_icon = static_cast<MockStatusIcon*>(
       status_tray->GetStatusIconsForTest().back().get());
 
-  auto* menu_item = status_icon->menu_item();
-  CheckMenuItemLabel(menu_item, 3, base::UTF8ToUTF16(profile_name));
+  // Check the current profile names.
+  {
+    auto* menu_item = status_icon->menu_item();
+    CheckMenuItemLabel(menu_item, 3, base::UTF8ToUTF16(profile_names[0]));
+    CheckMenuItemLabel(menu_item, 7, base::UTF8ToUTF16(profile_names[1]));
+  }
+
+  // Change the first profile name.
+  {
+    profile_manager()
+        ->profile_attributes_storage()
+        ->GetProfileAttributesWithPath(profile_paths[0])
+        ->SetLocalProfileName(base::UTF8ToUTF16(new_profile_names[0]),
+                              /*is_default_name*/ false);
+    auto* menu_item = status_icon->menu_item();
+    CheckMenuItemLabel(menu_item, 3, base::UTF8ToUTF16(new_profile_names[0]));
+    CheckMenuItemLabel(menu_item, 7, base::UTF8ToUTF16(profile_names[1]));
+  }
+
+  // Change the second profile name.
+  {
+    profile_manager()
+        ->profile_attributes_storage()
+        ->GetProfileAttributesWithPath(profile_paths[1])
+        ->SetLocalProfileName(base::UTF8ToUTF16(new_profile_names[1]),
+                              /*is_default_name*/ false);
+    auto* menu_item = status_icon->menu_item();
+    CheckMenuItemLabel(menu_item, 3, base::UTF8ToUTF16(new_profile_names[0]));
+    CheckMenuItemLabel(menu_item, 7, base::UTF8ToUTF16(new_profile_names[1]));
+  }
 }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/lacros/download_status_updater_lacros_browsertest.cc b/chrome/browser/lacros/download_status_updater_lacros_browsertest.cc
index 1df788b6..bb730d7 100644
--- a/chrome/browser/lacros/download_status_updater_lacros_browsertest.cc
+++ b/chrome/browser/lacros/download_status_updater_lacros_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/download/download_status_updater.h"
 
+#include "base/files/file_path.h"
 #include "base/observer_list.h"
 #include "base/uuid.h"
 #include "chrome/browser/browser_process.h"
@@ -14,6 +15,7 @@
 #include "chromeos/lacros/lacros_service.h"
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/mock_download_item.h"
+#include "content/public/browser/download_item_utils.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/mock_download_manager.h"
@@ -26,13 +28,30 @@
 // Aliases.
 using ::crosapi::mojom::DownloadState;
 using ::crosapi::mojom::DownloadStatus;
+using ::testing::Action;
 using ::testing::AllOf;
 using ::testing::Eq;
 using ::testing::Field;
+using ::testing::Invoke;
+using ::testing::Mock;
+using ::testing::NiceMock;
 using ::testing::Pointer;
 using ::testing::Return;
 using ::testing::ReturnRefOfCopy;
 
+// Actions ---------------------------------------------------------------------
+
+ACTION_P3(InvokeEq, invokee, invokable, expected) {
+  return (invokee->*invokable)() == expected;
+}
+
+ACTION_P2(ReturnAllOf, a, b) {
+  Action<bool()> action_a = a;
+  Action<bool()> action_b = b;
+  return action_a.Perform(std::forward_as_tuple()) &&
+         action_b.Perform(std::forward_as_tuple());
+}
+
 // MockDownloadManager ---------------------------------------------------------
 
 // A mock `content::DownloadManager` for testing which supports realistic
@@ -128,24 +147,24 @@
 
   // Returns the mock download manager registered with the download status
   // updater in Lacros Chrome.
-  testing::NiceMock<MockDownloadManager>& download_manager() {
+  NiceMock<MockDownloadManager>& download_manager() {
     return download_manager_;
   }
 
   // Returns the mock download status updater in Ash Chrome that can be observed
   // for interactions with Lacros Chrome.
-  testing::NiceMock<MockDownloadStatusUpdater>& download_status_updater() {
+  NiceMock<MockDownloadStatusUpdater>& download_status_updater() {
     return download_status_updater_;
   }
 
  private:
   // The mock download manager registered with the download status updater in
   // Lacros Chrome.
-  testing::NiceMock<MockDownloadManager> download_manager_;
+  NiceMock<MockDownloadManager> download_manager_;
 
   // The mock download status updater in Ash Chrome that can be observed for
   // interactions with Lacros Chrome.
-  testing::NiceMock<MockDownloadStatusUpdater> download_status_updater_;
+  NiceMock<MockDownloadStatusUpdater> download_status_updater_;
   mojo::Receiver<crosapi::mojom::DownloadStatusUpdater>
       download_status_updater_receiver_{&download_status_updater_};
 };
@@ -161,12 +180,32 @@
   }
 
   // Create a mock in-progress download `item`.
-  testing::NiceMock<download::MockDownloadItem> item;
+  NiceMock<download::MockDownloadItem> item;
   ON_CALL(item, GetGuid())
       .WillByDefault(
           ReturnRefOfCopy(base::Uuid::GenerateRandomV4().AsLowercaseString()));
   ON_CALL(item, GetState())
       .WillByDefault(Return(download::DownloadItem::IN_PROGRESS));
+  ON_CALL(item, GetReceivedBytes()).WillByDefault(Return(10));
+  ON_CALL(item, GetTotalBytes()).WillByDefault(Return(100));
+  ON_CALL(item, GetTargetFilePath())
+      .WillByDefault(ReturnRefOfCopy(base::FilePath("target_file_path")));
+
+  // Fulfill `CanResume()` dynamically based on `item` state and paused status.
+  ON_CALL(item, CanResume())
+      .WillByDefault(
+          ReturnAllOf(Invoke(&item, &download::DownloadItem::IsPaused),
+                      InvokeEq(&item, &download::DownloadItem::GetState,
+                               download::DownloadItem::IN_PROGRESS)));
+
+  // Fulfill `IsDone()` dynamically based on `item` state.
+  ON_CALL(item, IsDone())
+      .WillByDefault(InvokeEq(&item, &download::DownloadItem::GetState,
+                              download::DownloadItem::COMPLETE));
+
+  // Associate the download `item` with the browser `profile()`.
+  content::DownloadItemUtils::AttachInfoForTesting(&item, browser()->profile(),
+                                                   /*web_contents=*/nullptr);
 
   // Expect a `DownloadStatusUpdater::Update()` event in Ash Chrome when the
   // download status updater in Lacros Chrome is notified of `item` creation.
@@ -174,31 +213,71 @@
       download_status_updater(),
       Update(Pointer(AllOf(
           Field(&DownloadStatus::guid, Eq(item.GetGuid())),
-          Field(&DownloadStatus::state, Eq(DownloadState::kInProgress))))));
+          Field(&DownloadStatus::state, Eq(DownloadState::kInProgress)),
+          Field(&DownloadStatus::received_bytes, Eq(item.GetReceivedBytes())),
+          Field(&DownloadStatus::total_bytes, Eq(item.GetTotalBytes())),
+          Field(&DownloadStatus::target_file_path,
+                Eq(item.GetTargetFilePath())),
+          Field(&DownloadStatus::cancellable, Eq(true)),
+          Field(&DownloadStatus::pausable, Eq(true)),
+          Field(&DownloadStatus::resumable, Eq(false))))));
 
   // Notify the download status updater in Lacros Chrome of `item` creation and
   // verify Ash Chrome expectations.
   download_manager().NotifyDownloadCreated(&item);
   FlushInterfaceForTesting();
-  testing::Mock::VerifyAndClearExpectations(&download_status_updater());
+  Mock::VerifyAndClearExpectations(&download_status_updater());
+
+  // Pause `item`.
+  ON_CALL(item, IsPaused()).WillByDefault(Return(true));
 
   // Expect a `DownloadStatusUpdater::Update()` event in Ash Chrome when the
   // download status updater in Lacros Chrome is notified of `item` updates.
   EXPECT_CALL(
       download_status_updater(),
-      Update(Pointer(
-          AllOf(Field(&DownloadStatus::guid, Eq(item.GetGuid())),
-                Field(&DownloadStatus::state, Eq(DownloadState::kComplete))))));
-
-  // Update `item` state.
-  ON_CALL(item, GetState())
-      .WillByDefault(Return(download::DownloadItem::COMPLETE));
+      Update(Pointer(AllOf(
+          Field(&DownloadStatus::guid, Eq(item.GetGuid())),
+          Field(&DownloadStatus::state, Eq(DownloadState::kInProgress)),
+          Field(&DownloadStatus::received_bytes, Eq(item.GetReceivedBytes())),
+          Field(&DownloadStatus::total_bytes, Eq(item.GetTotalBytes())),
+          Field(&DownloadStatus::target_file_path,
+                Eq(item.GetTargetFilePath())),
+          Field(&DownloadStatus::cancellable, Eq(true)),
+          Field(&DownloadStatus::pausable, Eq(false)),
+          Field(&DownloadStatus::resumable, Eq(true))))));
 
   // Notify the download status updater in Lacros Chrome of `item` update and
   // verify Ash Chrome expectations.
   item.NotifyObserversDownloadUpdated();
   FlushInterfaceForTesting();
-  testing::Mock::VerifyAndClearExpectations(&download_status_updater());
+  Mock::VerifyAndClearExpectations(&download_status_updater());
+
+  // Complete `item`.
+  ON_CALL(item, GetState())
+      .WillByDefault(Return(download::DownloadItem::COMPLETE));
+  ON_CALL(item, GetReceivedBytes())
+      .WillByDefault(Invoke(&item, &download::DownloadItem::GetTotalBytes));
+
+  // Expect a `DownloadStatusUpdater::Update()` event in Ash Chrome when the
+  // download status updater in Lacros Chrome is notified of `item` updates.
+  EXPECT_CALL(
+      download_status_updater(),
+      Update(Pointer(AllOf(
+          Field(&DownloadStatus::guid, Eq(item.GetGuid())),
+          Field(&DownloadStatus::state, Eq(DownloadState::kComplete)),
+          Field(&DownloadStatus::received_bytes, Eq(item.GetReceivedBytes())),
+          Field(&DownloadStatus::total_bytes, Eq(item.GetTotalBytes())),
+          Field(&DownloadStatus::target_file_path,
+                Eq(item.GetTargetFilePath())),
+          Field(&DownloadStatus::cancellable, Eq(false)),
+          Field(&DownloadStatus::pausable, Eq(false)),
+          Field(&DownloadStatus::resumable, Eq(false))))));
+
+  // Notify the download status updater in Lacros Chrome of `item` update and
+  // verify Ash Chrome expectations.
+  item.NotifyObserversDownloadUpdated();
+  FlushInterfaceForTesting();
+  Mock::VerifyAndClearExpectations(&download_status_updater());
 }
 
 }  // namespace
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
index cd69a364..7db3401 100644
--- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
+++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -102,7 +102,7 @@
 
 BASE_FEATURE(kPrewarmLookalikeCheck,
              "PrewarmLookalikeCheck",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 LookalikeUrlNavigationThrottle::LookalikeUrlNavigationThrottle(
     content::NavigationHandle* navigation_handle)
@@ -130,7 +130,7 @@
   if (base::FeatureList::IsEnabled(kPrewarmLookalikeCheck) &&
       redirect_lookup_cache_checks_ <
           base::GetFieldTrialParamByFeatureAsInt(
-              kPrewarmLookalikeCheck, "redirect_lookup_cache_limit", 10)) {
+              kPrewarmLookalikeCheck, "redirect_lookup_cache_limit", 2)) {
     redirect_lookup_cache_checks_++;
     PrewarmLookalikeCheckAsync();
   }
diff --git a/chrome/browser/mac/relauncher.mm b/chrome/browser/mac/relauncher.mm
index aab5837..d3251fd 100644
--- a/chrome/browser/mac/relauncher.mm
+++ b/chrome/browser/mac/relauncher.mm
@@ -339,16 +339,14 @@
         {.activate = activate,
          .create_new_instance = true,
          .prompt_user_if_needed = true},
-        base::BindOnce(
-            [](base::expected<NSRunningApplication*, NSError*> result) {
-              if (!result.has_value()) {
-                LOG(ERROR) << "Failed to relaunch: "
-                           << base::SysNSStringToUTF8(
-                                  result.error().description);
-              }
+        base::BindOnce([](NSRunningApplication* app, NSError* error) {
+          if (error) {
+            LOG(ERROR) << "Failed to relaunch: "
+                       << base::SysNSStringToUTF8(error.description);
+          }
 
-              CFRunLoopStop(CFRunLoopGetMain());
-            }));
+          CFRunLoopStop(CFRunLoopGetMain());
+        }));
 
     // This is running the main thread.
     CFRunLoopRun();
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 1244dac..51d6745 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -315,7 +315,7 @@
       // TODO(crbug.com/1412485): Remove this line so that real hardware
       // capabilities can be checked.
       command_line->AppendSwitchASCII(
-          switches::kOverrideHardwareSecureCodecsForTesting, "avc1");
+          switches::kOverrideHardwareSecureCodecsForTesting, "avc1,mp4a");
     }
 #endif  // BUILDFLAG(IS_WIN)
 
@@ -1061,17 +1061,30 @@
 }
 
 IN_PROC_BROWSER_TEST_F(MediaFoundationEncryptedMediaTest,
-                       Playback_EncryptedAudioCbcs_MediaTypeUnsupported) {
+                       Playback_EncryptedCencAudio_Success) {
+  if (!IsMediaFoundationEncryptedPlaybackSupported()) {
+    GTEST_SKIP();
+  }
+
+  TestLicenseExchange("bear-640x360-a_frag-cenc.mp4");  // MP4 AAC audio only
+}
+
+IN_PROC_BROWSER_TEST_F(MediaFoundationEncryptedMediaTest,
+                       Playback_EncryptedVp9CencAudio_MediaTypeUnsupported) {
   if (!IsMediaFoundationEncryptedPlaybackSupported()) {
     GTEST_SKIP();
   }
 
   // MediaFoundation Clear Key Key System supports only H.264 videos
-  // (codecs=avc1.64001E). See AddMediaFoundationClearKey() in
+  // (codecs="avc1.64001E") and MP4 audios (codecs="mp4a.40.2"). See
+  // AddMediaFoundationClearKey() in
   // components/cdm/renderer/key_system_support_update.cc
-  RunEncryptedMediaTest(
-      kDefaultEmePlayer, "bear-640x360-a_frag-cbcs.mp4" /*codecs=mp4a.40.2*/,
-      media::kMediaFoundationClearKeyKeySystem, SrcType::MSE, kNoSessionToLoad,
-      false, PlayCount::ONCE, kEmeNotSupportedError);
+  RunEncryptedMediaTest(kDefaultEmePlayer,
+                        "bear-320x240-v_frag-vp9-cenc.mp4"
+                        /*codecs="vp09.00.10.08.01.02.02.02.00"*/
+                        ,
+                        media::kMediaFoundationClearKeyKeySystem, SrcType::MSE,
+                        kNoSessionToLoad, false, PlayCount::ONCE,
+                        kEmeNotSupportedError);
 }
 #endif  // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/chrome/browser/nearby_sharing/certificates/BUILD.gn b/chrome/browser/nearby_sharing/certificates/BUILD.gn
index d0c46d6..9b01197 100644
--- a/chrome/browser/nearby_sharing/certificates/BUILD.gn
+++ b/chrome/browser/nearby_sharing/certificates/BUILD.gn
@@ -88,6 +88,7 @@
     "//base/test:test_support",
     "//chrome/browser/nearby_sharing/client:test_support",
     "//chrome/browser/nearby_sharing/common",
+    "//chrome/browser/nearby_sharing/common:test_support",
     "//chrome/browser/nearby_sharing/contacts:test_support",
     "//chrome/browser/nearby_sharing/local_device_data:test_support",
     "//chrome/browser/nearby_sharing/proto",
diff --git a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc
index 62b7a8a..e250d19f 100644
--- a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc
+++ b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc
@@ -15,6 +15,7 @@
 FakeNearbyShareCertificateManager::Factory::CreateInstance(
     NearbyShareLocalDeviceDataManager* local_device_data_manager,
     NearbyShareContactManager* contact_manager,
+    NearbyShareProfileInfoProvider* profile_info_provider,
     PrefService* pref_service,
     leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
     const base::FilePath& profile_path,
diff --git a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h
index 38219c1..992b2e9 100644
--- a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h
+++ b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h
@@ -16,6 +16,8 @@
 #include "chrome/browser/nearby_sharing/certificates/nearby_share_private_certificate.h"
 #include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
 
+class NearbyShareProfileInfoProvider;
+
 // A fake implementation of NearbyShareCertificateManager, along with a fake
 // factory, to be used in tests.
 class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager {
@@ -39,6 +41,7 @@
     std::unique_ptr<NearbyShareCertificateManager> CreateInstance(
         NearbyShareLocalDeviceDataManager* local_device_data_manager,
         NearbyShareContactManager* contact_manager,
+        NearbyShareProfileInfoProvider* profile_info_provider,
         PrefService* pref_service,
         leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
         const base::FilePath& profile_path,
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc
index e2dc1ee..485e202 100644
--- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc
+++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_storage_impl.h"
 #include "chrome/browser/nearby_sharing/client/nearby_share_client.h"
 #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
+#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h"
 #include "chrome/browser/nearby_sharing/common/nearby_share_switches.h"
 #include "chrome/browser/nearby_sharing/logging/logging.h"
 #include "chrome/browser/nearby_sharing/proto/certificate_rpc.pb.h"
@@ -113,6 +114,7 @@
     std::string device_name,
     absl::optional<std::string> full_name,
     absl::optional<std::string> icon_url,
+    absl::optional<std::string> account_name,
     device::BluetoothAdapter* bluetooth_adapter) {
   nearbyshare::proto::EncryptedMetadata metadata;
   if (device_name.empty()) {
@@ -129,6 +131,9 @@
   if (icon_url) {
     metadata.set_icon_url(*icon_url);
   }
+  if (account_name) {
+    metadata.set_account_name(*account_name);
+  }
 
   absl::optional<std::string> bluetooth_mac_address =
       GetBluetoothMacAddress(bluetooth_adapter);
@@ -227,6 +232,7 @@
 NearbyShareCertificateManagerImpl::Factory::Create(
     NearbyShareLocalDeviceDataManager* local_device_data_manager,
     NearbyShareContactManager* contact_manager,
+    NearbyShareProfileInfoProvider* profile_info_provider,
     PrefService* pref_service,
     leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
     const base::FilePath& profile_path,
@@ -235,14 +241,16 @@
   DCHECK(clock);
 
   if (test_factory_) {
-    return test_factory_->CreateInstance(
-        local_device_data_manager, contact_manager, pref_service,
-        proto_database_provider, profile_path, client_factory, clock);
+    return test_factory_->CreateInstance(local_device_data_manager,
+                                         contact_manager, profile_info_provider,
+                                         pref_service, proto_database_provider,
+                                         profile_path, client_factory, clock);
   }
 
   return base::WrapUnique(new NearbyShareCertificateManagerImpl(
-      local_device_data_manager, contact_manager, pref_service,
-      proto_database_provider, profile_path, client_factory, clock));
+      local_device_data_manager, contact_manager, profile_info_provider,
+      pref_service, proto_database_provider, profile_path, client_factory,
+      clock));
 }
 
 // static
@@ -256,6 +264,7 @@
 NearbyShareCertificateManagerImpl::NearbyShareCertificateManagerImpl(
     NearbyShareLocalDeviceDataManager* local_device_data_manager,
     NearbyShareContactManager* contact_manager,
+    NearbyShareProfileInfoProvider* profile_info_provider,
     PrefService* pref_service,
     leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
     const base::FilePath& profile_path,
@@ -263,6 +272,7 @@
     const base::Clock* clock)
     : local_device_data_manager_(local_device_data_manager),
       contact_manager_(contact_manager),
+      profile_info_provider_(profile_info_provider),
       pref_service_(pref_service),
       client_factory_(client_factory),
       clock_(clock),
@@ -485,6 +495,7 @@
       BuildMetadata(local_device_data_manager_->GetDeviceName(),
                     local_device_data_manager_->GetFullName(),
                     local_device_data_manager_->GetIconUrl(),
+                    profile_info_provider_->GetProfileUserName(),
                     bluetooth_adapter.get());
   if (!metadata) {
     NS_LOG(WARNING)
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h
index 9715d2a1..8a21064 100644
--- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h
+++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h
@@ -29,6 +29,7 @@
 class NearbyShareClient;
 class NearbyShareClientFactory;
 class NearbyShareLocalDeviceDataManager;
+class NearbyShareProfileInfoProvider;
 class PrefService;
 
 namespace device {
@@ -68,6 +69,7 @@
     static std::unique_ptr<NearbyShareCertificateManager> Create(
         NearbyShareLocalDeviceDataManager* local_device_data_manager,
         NearbyShareContactManager* contact_manager,
+        NearbyShareProfileInfoProvider* profile_info_provider,
         PrefService* pref_service,
         leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
         const base::FilePath& profile_path,
@@ -80,6 +82,7 @@
     virtual std::unique_ptr<NearbyShareCertificateManager> CreateInstance(
         NearbyShareLocalDeviceDataManager* local_device_data_manager,
         NearbyShareContactManager* contact_manager,
+        NearbyShareProfileInfoProvider* profile_info_provider,
         PrefService* pref_service,
         leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
         const base::FilePath& profile_path,
@@ -96,6 +99,7 @@
   NearbyShareCertificateManagerImpl(
       NearbyShareLocalDeviceDataManager* local_device_data_manager,
       NearbyShareContactManager* contact_manager,
+      NearbyShareProfileInfoProvider* profile_info_provider,
       PrefService* pref_service,
       leveldb_proto::ProtoDatabaseProvider* proto_database_provider,
       const base::FilePath& profile_path,
@@ -194,6 +198,8 @@
       local_device_data_manager_ = nullptr;
   raw_ptr<NearbyShareContactManager, ExperimentalAsh> contact_manager_ =
       nullptr;
+  raw_ptr<NearbyShareProfileInfoProvider, ExperimentalAsh>
+      profile_info_provider_ = nullptr;
   raw_ptr<PrefService, ExperimentalAsh> pref_service_ = nullptr;
   raw_ptr<NearbyShareClientFactory, ExperimentalAsh> client_factory_ = nullptr;
   raw_ptr<const base::Clock, ExperimentalAsh> clock_;
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc
index 9c00bf33..0827afc8 100644
--- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc
+++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager.h"
 #include "chrome/browser/nearby_sharing/certificates/test_util.h"
 #include "chrome/browser/nearby_sharing/client/fake_nearby_share_client.h"
+#include "chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h"
 #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
 #include "chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h"
 #include "chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h"
@@ -35,6 +36,7 @@
 const char kDeviceIdPrefix[] = "users/me/devices/";
 const char kDeviceId[] = "123456789A";
 const char kDefaultDeviceName[] = "Josh's Chromebook";
+const char kTestProfileUserName[] = "test@google.com";
 
 const std::vector<std::string> kPublicCertificateIds = {"id1", "id2", "id3"};
 
@@ -61,6 +63,10 @@
 
     contact_manager_ = std::make_unique<FakeNearbyShareContactManager>();
 
+    profile_info_provider_ =
+        std::make_unique<FakeNearbyShareProfileInfoProvider>();
+    profile_info_provider_->set_profile_user_name(kTestProfileUserName);
+
     pref_service_ = std::make_unique<TestingPrefServiceSimple>();
     pref_service_->registry()->RegisterDictionaryPref(
         prefs::kNearbySharingSchedulerDownloadPublicCertificatesPrefName);
@@ -81,7 +87,7 @@
 
     cert_manager_ = NearbyShareCertificateManagerImpl::Factory::Create(
         local_device_data_manager_.get(), contact_manager_.get(),
-        pref_service_.get(),
+        profile_info_provider_.get(), pref_service_.get(),
         /*proto_database_provider=*/nullptr, base::FilePath(), &client_factory_,
         task_environment_.GetMockClock());
     cert_manager_->AddObserver(this);
@@ -389,6 +395,7 @@
     metadata2.set_full_name("full_name2");
     metadata2.set_icon_url("icon_url2");
     metadata2.set_bluetooth_mac_address("bluetooth_mac_address2");
+    metadata2.set_account_name("account_name2");
     for (auto metadata : {metadata1, metadata2}) {
       auto private_cert = NearbySharePrivateCertificate(
           nearby_share::mojom::Visibility::kAllContacts, t0, metadata);
@@ -422,6 +429,7 @@
   std::unique_ptr<FakeNearbyShareLocalDeviceDataManager>
       local_device_data_manager_;
   std::unique_ptr<FakeNearbyShareContactManager> contact_manager_;
+  std::unique_ptr<FakeNearbyShareProfileInfoProvider> profile_info_provider_;
   std::unique_ptr<TestingPrefServiceSimple> pref_service_;
   std::unique_ptr<NearbyShareCertificateManager> cert_manager_;
 };
@@ -760,6 +768,26 @@
 }
 
 TEST_F(NearbyShareCertificateManagerImplTest,
+       RefreshPrivateCertificates_MissingAccountName) {
+  cert_store_->ReplacePrivateCertificates(
+      std::vector<NearbySharePrivateCertificate>());
+
+  // Full name and icon URL are missing in local device data manager.
+  profile_info_provider_->set_profile_user_name(absl::nullopt);
+
+  cert_manager_->Start();
+  HandlePrivateCertificateRefresh(/*expect_private_cert_refresh=*/true,
+                                  /*expected_success=*/true);
+  RunUpload(/*success=*/true);
+
+  // The account name isn't set.
+  nearbyshare::proto::EncryptedMetadata metadata = GetNearbyShareTestMetadata();
+  metadata.clear_account_name();
+
+  VerifyPrivateCertificates(/*expected_metadata=*/metadata);
+}
+
+TEST_F(NearbyShareCertificateManagerImplTest,
        RemoveExpiredPublicCertificates_Success) {
   cert_manager_->Start();
 
diff --git a/chrome/browser/nearby_sharing/certificates/test_util.cc b/chrome/browser/nearby_sharing/certificates/test_util.cc
index fe4319c5..64a4549 100644
--- a/chrome/browser/nearby_sharing/certificates/test_util.cc
+++ b/chrome/browser/nearby_sharing/certificates/test_util.cc
@@ -77,14 +77,15 @@
                                              0xb5, 0x40, 0xe8, 0xe2, 0xbd,
                                              0xa0, 0xee, 0x9d, 0x7b};
 
+// TODO fix
 const uint8_t kTestEncryptedMetadata[] = {
-    0x4d, 0x59, 0x5d, 0xb6, 0xac, 0x70, 0x00, 0x8f, 0x32, 0x9d, 0x0d, 0xcf,
-    0xc3, 0x8b, 0x01, 0x19, 0x1d, 0xad, 0x2e, 0xb4, 0x62, 0xec, 0xf3, 0xa5,
-    0xe4, 0x89, 0x51, 0x37, 0x0d, 0x78, 0xad, 0x9d, 0x2e, 0xe5, 0x99, 0xd5,
-    0xf7, 0x1d, 0x71, 0x47, 0xef, 0x33,
-    // tag
-    0x63, 0x47, 0xae, 0xb0, 0xdf, 0x67, 0x07, 0x16, 0x70, 0x97, 0x3d, 0x8f,
-    0xc8, 0xe6, 0x61, 0xc0};
+    0x4d, 0x59, 0x5d, 0xb6, 0xac, 0x70, 0x00, 0x8f, 0x32, 0x9d, 0x0d,
+    0xcf, 0xc3, 0x8b, 0x01, 0x19, 0x1d, 0xad, 0x2e, 0xb4, 0x62, 0xec,
+    0xf3, 0xa5, 0xe4, 0x89, 0x51, 0x37, 0x0d, 0x78, 0xad, 0x9d, 0x2e,
+    0xe5, 0x99, 0xd5, 0xf7, 0x1d, 0x71, 0x47, 0xef, 0x33, 0xae, 0x4f,
+    0xf0, 0xd0, 0x4b, 0xcf, 0x1e, 0xaf, 0x06, 0xfa, 0x08, 0x79, 0x9b,
+    0x76, 0x44, 0x13, 0xad, 0x08, 0x68, 0xef, 0x0a, 0xc5, 0x13, 0xd0,
+    0xe8, 0xaa, 0xbe, 0x52, 0x28, 0xb1, 0xb6, 0xc4, 0x20};
 
 // Plaintext "sample" (from RFC 6979 A.2.5).
 const uint8_t kTestPayloadToSign[] = {0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65};
@@ -126,6 +127,7 @@
 const char kTestMetadataFullName[] = "full_name";
 const char kTestMetadataIconUrl[] = "icon_url";
 const char kTestUnparsedBluetoothMacAddress[] = "4E:65:61:72:62:79";
+const char kTestAccountName[] = "test@google.com";
 
 std::unique_ptr<crypto::ECPrivateKey> GetNearbyShareTestP256KeyPair() {
   return crypto::ECPrivateKey::CreateFromPrivateKeyInfo(kTestPrivateKeyBytes);
@@ -203,6 +205,7 @@
         metadata.set_full_name(kTestMetadataFullName);
         metadata.set_icon_url(kTestMetadataIconUrl);
         metadata.set_bluetooth_mac_address(bytes.data(), 6u);
+        metadata.set_account_name(kTestAccountName);
         return metadata;
       }());
   return *metadata;
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
index 48e343e..01f9b309 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -312,6 +312,7 @@
       certificate_manager_(NearbyShareCertificateManagerImpl::Factory::Create(
           local_device_data_manager_.get(),
           contact_manager_.get(),
+          profile_info_provider_.get(),
           prefs,
           profile->GetDefaultStoragePartition()->GetProtoDatabaseProvider(),
           profile->GetPath(),
diff --git a/chrome/browser/nearby_sharing/proto/encrypted_metadata.proto b/chrome/browser/nearby_sharing/proto/encrypted_metadata.proto
index d157baef..2d1139e 100644
--- a/chrome/browser/nearby_sharing/proto/encrypted_metadata.proto
+++ b/chrome/browser/nearby_sharing/proto/encrypted_metadata.proto
@@ -4,7 +4,7 @@
 
 // Keep in sync with
 // http://google3/location/nearby/sharing/proto/contact_certificates.proto.
-// Messages not used in Chrome have been omitted. Last copied at cl/310853364.
+// Messages not used in Chrome have been omitted. Last copied at cl/424750446.
 
 syntax = "proto2";
 
@@ -27,4 +27,7 @@
 
   // The obfuscated Gaia ID of the account which created the certificate.
   optional string obfuscated_gaia_id = 5;
+
+  // The name of the account which created the certificate.
+  optional string account_name = 6;
 }
diff --git a/chrome/browser/notifications/scheduler/notification_schedule_service_factory.cc b/chrome/browser/notifications/scheduler/notification_schedule_service_factory.cc
index 6473a6b6..ffb5068 100644
--- a/chrome/browser/notifications/scheduler/notification_schedule_service_factory.cc
+++ b/chrome/browser/notifications/scheduler/notification_schedule_service_factory.cc
@@ -23,11 +23,8 @@
 #include "content/public/browser/storage_partition.h"
 
 #if BUILDFLAG(IS_ANDROID)
-#include "chrome/browser/android/reading_list/reading_list_notification_service_factory.h"
 #include "chrome/browser/notifications/scheduler/display_agent_android.h"
 #include "chrome/browser/notifications/scheduler/notification_background_task_scheduler_android.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_client.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
 #endif  // BUILDFLAG(IS_ANDROID)
 
 namespace {
@@ -37,19 +34,6 @@
   auto client_registrar =
       std::make_unique<notifications::NotificationSchedulerClientRegistrar>();
 #if BUILDFLAG(IS_ANDROID)
-  // Register reading list client.
-  if (ReadingListNotificationService::IsEnabled()) {
-    Profile* profile = ProfileManager::GetProfileFromProfileKey(key);
-    auto reading_list_service_getter = base::BindRepeating(
-        &ReadingListNotificationServiceFactory::GetForBrowserContext, profile);
-
-    auto reading_list_client = std::make_unique<ReadingListNotificationClient>(
-        reading_list_service_getter);
-    client_registrar->RegisterClient(
-        notifications::SchedulerClientType::kReadingList,
-        std::move(reading_list_client));
-  }
-
   if (base::FeatureList::IsEnabled(
           feature_guide::features::kFeatureNotificationGuide)) {
     Profile* profile = ProfileManager::GetProfileFromProfileKey(key);
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn
index 4a311f2..4b881dd 100644
--- a/chrome/browser/password_manager/android/BUILD.gn
+++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -450,6 +450,7 @@
     "//chrome/app:generated_resources",
     "//chrome/browser",
     "//chrome/browser/autofill",
+    "//chrome/browser/password_manager/android/pwd_migration:utils",
     "//chrome/test:test_support",
     "//components/autofill/core/browser",
     "//components/autofill/core/common",
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
new file mode 100644
index 0000000..3d20bf7
--- /dev/null
+++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
@@ -0,0 +1,16 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h"
+#include "chrome/browser/password_manager/android/pwd_migration/jni_headers/PasswordMigrationWarningBridge_jni.h"
+#include "ui/android/window_android.h"
+
+using base::android::AttachCurrentThread;
+
+namespace password_manager {
+void ShowWarning(const gfx::NativeWindow window) {
+  Java_PasswordMigrationWarningBridge_showWarning(AttachCurrentThread(),
+                                                  window->GetJavaObject());
+}
+}  // namespace password_manager
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h
new file mode 100644
index 0000000..8f5a8e4
--- /dev/null
+++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.h
@@ -0,0 +1,14 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_LOCAL_PASSWORDS_MIGRATION_WARNING_UTIL_H_
+#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_LOCAL_PASSWORDS_MIGRATION_WARNING_UTIL_H_
+
+#include "ui/gfx/native_widget_types.h"
+
+namespace password_manager {
+void ShowWarning(const gfx::NativeWindow window);
+}
+
+#endif  // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_LOCAL_PASSWORDS_MIGRATION_WARNING_UTIL_H_
diff --git a/chrome/browser/password_manager/android/pwd_migration/BUILD.gn b/chrome/browser/password_manager/android/pwd_migration/BUILD.gn
new file mode 100644
index 0000000..303b833
--- /dev/null
+++ b/chrome/browser/password_manager/android/pwd_migration/BUILD.gn
@@ -0,0 +1,43 @@
+# Copyright 2020 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+source_set("utils") {
+  sources = [
+    "../local_passwords_migration_warning_util.cc",
+    "../local_passwords_migration_warning_util.h",
+  ]
+
+  deps = [
+    ":jni_headers",
+    "//ui/android:android",
+    "//ui/gfx:native_widget_types",
+  ]
+}
+
+generate_jni("jni_headers") {
+  visibility = [
+    ":utils",
+    "//chrome/browser",
+  ]
+  sources = [ "java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningBridge.java" ]
+}
+
+android_library("java") {
+  annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+
+  deps = [
+    "//base:base_java",
+    "//base:jni_java",
+    "//components/browser_ui/bottomsheet/android:java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
+    "//ui/android:ui_java",
+  ]
+
+  sources = [
+    "java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningBridge.java",
+    "java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java",
+  ]
+}
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningBridge.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningBridge.java
new file mode 100644
index 0000000..cd10205
--- /dev/null
+++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningBridge.java
@@ -0,0 +1,24 @@
+// Copyright 2023 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.pwd_migration;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
+import org.chromium.ui.base.WindowAndroid;
+
+/** The bridge that is used to show the password migration warning. */
+class PasswordMigrationWarningBridge {
+    @CalledByNative
+    static void showWarning(WindowAndroid windowAndroid) {
+        BottomSheetController bottomSheetController =
+                BottomSheetControllerProvider.from(windowAndroid);
+        if (bottomSheetController == null) return;
+        PasswordMigrationWarningCoordinator passwordMigrationWarningCoordinator =
+                new PasswordMigrationWarningCoordinator(
+                        windowAndroid.getContext().get(), bottomSheetController);
+        passwordMigrationWarningCoordinator.showWarning();
+    }
+}
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java
new file mode 100644
index 0000000..6f26040
--- /dev/null
+++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java
@@ -0,0 +1,21 @@
+// Copyright 2023 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.pwd_migration;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+
+/** The coordinator of the password migration warning. */
+class PasswordMigrationWarningCoordinator {
+    public PasswordMigrationWarningCoordinator(
+            @Nullable Context context, BottomSheetController sheetController) {}
+
+    public void showWarning() {
+        // TODO(crbug.com/1439761): Implement.
+    }
+}
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
index 7f336d6..7f9ff44 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/password_manager/android/save_update_password_message_delegate.h"
 #include <utility>
 
+#include "base/android/jni_android.h"
 #include "base/check.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
@@ -13,6 +14,7 @@
 #include "chrome/browser/android/android_theme_resources.h"
 #include "chrome/browser/android/resource_mapper.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
+#include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h"
 #include "chrome/browser/password_manager/android/password_infobar_utils.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
@@ -95,11 +97,16 @@
 
 SaveUpdatePasswordMessageDelegate::SaveUpdatePasswordMessageDelegate()
     : SaveUpdatePasswordMessageDelegate(
-          base::BindRepeating(PasswordEditDialogBridge::Create)) {}
+          base::BindRepeating(PasswordEditDialogBridge::Create),
+          base::BindRepeating(&password_manager::ShowWarning)) {}
 
 SaveUpdatePasswordMessageDelegate::SaveUpdatePasswordMessageDelegate(
-    PasswordEditDialogFactory password_edit_dialog_factory)
-    : password_edit_dialog_factory_(std::move(password_edit_dialog_factory)) {}
+    PasswordEditDialogFactory password_edit_dialog_factory,
+    base::RepeatingCallback<void(gfx::NativeWindow)>
+        create_migration_warning_callback)
+    : password_edit_dialog_factory_(std::move(password_edit_dialog_factory)),
+      create_migration_warning_callback_(
+          std::move(create_migration_warning_callback)) {}
 
 SaveUpdatePasswordMessageDelegate::~SaveUpdatePasswordMessageDelegate() {
   DCHECK(web_contents_ == nullptr);
@@ -408,6 +415,15 @@
 
 void SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked() {
   passwords_state_.form_manager()->Save();
+
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::
+              kUnifiedPasswordManagerLocalPasswordsMigrationWarning)) {
+    // TODO(crbug.com/439853): Check if the bottom sheet was shown a month ago
+    // or more.
+    std::move(create_migration_warning_callback_)
+        .Run(web_contents_->GetTopLevelNativeWindow());
+  }
 }
 
 void SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked() {
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.h b/chrome/browser/password_manager/android/save_update_password_message_delegate.h
index 6de7dd04..7227ace 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate.h
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.h
@@ -11,6 +11,7 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/password_edit_dialog/android/password_edit_dialog_bridge.h"
+#include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h"
 #include "chrome/browser/ui/passwords/manage_passwords_state.h"
 #include "components/messages/android/message_enums.h"
 #include "components/messages/android/message_wrapper.h"
@@ -77,7 +78,9 @@
   enum class SavePasswordDialogMenuItem { kNeverSave = 0, kEditPassword = 1 };
 
   SaveUpdatePasswordMessageDelegate(
-      PasswordEditDialogFactory password_edit_dialog_factory);
+      PasswordEditDialogFactory password_edit_dialog_factory,
+      base::RepeatingCallback<void(gfx::NativeWindow)>
+          password_migration_warning_bridge_callback);
 
   void DismissSaveUpdatePasswordMessage(messages::DismissReason dismiss_reason);
 
@@ -164,6 +167,8 @@
 
   std::unique_ptr<messages::MessageWrapper> message_;
   std::unique_ptr<PasswordEditDialog> password_edit_dialog_;
+  base::RepeatingCallback<void(gfx::NativeWindow)>
+      create_migration_warning_callback_;
 };
 
 #endif  // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_UPDATE_PASSWORD_MESSAGE_DELEGATE_H_
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
index 1e1354b..bbe044f 100644
--- a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
+++ b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
@@ -3,20 +3,24 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/password_manager/android/save_update_password_message_delegate.h"
+#include <jni.h>
 #include <algorithm>
 #include <memory>
 
 #include "base/android/jni_android.h"
+#include "base/functional/callback_forward.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/with_feature_override.h"
 #include "chrome/browser/android/android_theme_resources.h"
 #include "chrome/browser/android/resource_mapper.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
+#include "chrome/browser/password_manager/android/local_passwords_migration_warning_util.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
@@ -34,8 +38,11 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/native_widget_types.h"
 #include "url/gurl.h"
 
+using base::MockCallback;
+using base::RepeatingCallback;
 using base::test::FeatureRef;
 using base::test::FeatureRefAndParams;
 using password_manager::MockPasswordFormManagerForUI;
@@ -142,6 +149,9 @@
   // expectations.
   MockPasswordEditDialog* PreparePasswordEditDialog();
 
+  base::MockCallback<RepeatingCallback<void(gfx::NativeWindow)>>&
+  GetMigrationWarningCallback();
+
   void TriggerDialogAcceptedCallback(const std::u16string& username,
                                      const std::u16string& password);
   void TriggerLegacyDialogAcceptedCallback(int selected_username_index);
@@ -187,6 +197,8 @@
   PasswordEditDialog::LegacyDialogAcceptedCallback
       legacy_dialog_accepted_callback_;
   PasswordEditDialog::DialogDismissedCallback dialog_dismissed_callback_;
+  base::MockCallback<RepeatingCallback<void(gfx::NativeWindow)>>
+      mock_password_migration_warning_callback_;
 };
 
 class SaveUpdatePasswordMessageDelegateWithFeaturesTest
@@ -207,11 +219,8 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-SaveUpdatePasswordMessageDelegateTest::SaveUpdatePasswordMessageDelegateTest()
-    : delegate_(base::WrapUnique(
-          new SaveUpdatePasswordMessageDelegate(base::BindRepeating(
-              &SaveUpdatePasswordMessageDelegateTest::CreatePasswordEditDialog,
-              base::Unretained(this))))) {}
+SaveUpdatePasswordMessageDelegateTest::SaveUpdatePasswordMessageDelegateTest() =
+    default;
 
 void SaveUpdatePasswordMessageDelegateTest::SetUp() {
   ChromeRenderViewHostTestHarness::SetUp();
@@ -222,6 +231,13 @@
       true /*is_main_frame_secure*/, ukm_source_id_, nullptr /*pref_service*/);
   NavigateAndCommit(GURL(kDefaultUrl));
 
+  // Using `new` and `WrapUnique` to access a non-public constructor.
+  delegate_ = base::WrapUnique(new SaveUpdatePasswordMessageDelegate(
+      base::BindRepeating(
+          &SaveUpdatePasswordMessageDelegateTest::CreatePasswordEditDialog,
+          base::Unretained(this)),
+      mock_password_migration_warning_callback_.Get()));
+
   messages::MessageDispatcherBridge::SetInstanceForTesting(
       &message_dispatcher_bridge_);
 }
@@ -363,6 +379,11 @@
   return mock_password_edit_dialog_.get();
 }
 
+base::MockCallback<RepeatingCallback<void(gfx::NativeWindow)>>&
+SaveUpdatePasswordMessageDelegateTest::GetMigrationWarningCallback() {
+  return mock_password_migration_warning_callback_;
+}
+
 void SaveUpdatePasswordMessageDelegateTest::TriggerDialogAcceptedCallback(
     const std::u16string& username,
     const std::u16string& password) {
@@ -588,6 +609,25 @@
       password_manager::metrics_util::CLICKED_ACCEPT, 1);
 }
 
+// Tests that local password migration warning will show when the user clicks
+// "Save" button.
+TEST_F(SaveUpdatePasswordMessageDelegateTest,
+       TriggerLocalPasswordMigrationWarning_OnSaveClicked) {
+  base::test::ScopedFeatureList scoped_feature_state;
+  scoped_feature_state.InitAndEnableFeature(
+      password_manager::features::
+          kUnifiedPasswordManagerLocalPasswordsMigrationWarning);
+  auto form_manager =
+      CreateFormManager(GURL(kDefaultUrl), empty_best_matches());
+  EXPECT_CALL(*form_manager, Save());
+  EnqueueMessage(std::move(form_manager), /*user_signed_in=*/false,
+                 /*update_password=*/false);
+  EXPECT_NE(nullptr, GetMessageWrapper());
+  EXPECT_CALL(GetMigrationWarningCallback(), Run(_));
+  TriggerActionClick();
+  EXPECT_EQ(nullptr, GetMessageWrapper());
+}
+
 // Tests that password form is not saved and metrics recorded correctly when the
 // user dismisses the message.
 TEST_F(SaveUpdatePasswordMessageDelegateTest, DontSaveOnDismiss) {
diff --git a/chrome/browser/performance_manager/DEPS b/chrome/browser/performance_manager/DEPS
index 08896c8..a02f9a1e 100644
--- a/chrome/browser/performance_manager/DEPS
+++ b/chrome/browser/performance_manager/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+components/performance_manager",
-  "+chromeos/ash/components/memory"
+  "+chromeos/ash/components/memory",
+  "+dbus"
 ]
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
index 98609be..00b1dc25 100644
--- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
+++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -8,6 +8,7 @@
 
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
+#include "base/power_monitor/battery_state_sampler.h"
 #include "base/power_monitor/power_monitor_buildflags.h"
 #include "base/system/sys_info.h"
 #include "base/time/default_tick_clock.h"
@@ -65,7 +66,6 @@
 #endif
 
 #if !BUILDFLAG(IS_ANDROID)
-#include "base/power_monitor/battery_state_sampler.h"
 #include "chrome/browser/performance_manager/mechanisms/page_freezer.h"
 #include "chrome/browser/performance_manager/policies/heuristic_memory_saver_policy.h"
 #include "chrome/browser/performance_manager/policies/high_efficiency_mode_policy.h"
diff --git a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
index d38b3e2..abbd9bc 100644
--- a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
+++ b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_USER_TUNING_USER_PERFORMANCE_TUNING_MANAGER_H_
 #define CHROME_BROWSER_PERFORMANCE_MANAGER_PUBLIC_USER_TUNING_USER_PERFORMANCE_TUNING_MANAGER_H_
 
+#include <memory>
+
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
-#include "base/power_monitor/battery_state_sampler.h"
-#include "base/power_monitor/power_observer.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
 #include "chrome/browser/performance_manager/user_tuning/user_performance_tuning_notifier.h"
@@ -33,9 +33,7 @@
 // - Starts to manage the modes when Start() is called in PreMainMessageLoopRun.
 //
 // This object lives on the main thread and should be used from it exclusively.
-class UserPerformanceTuningManager
-    : public base::PowerStateObserver,
-      public base::BatteryStateSampler::Observer {
+class UserPerformanceTuningManager {
  public:
   // The percentage of battery that is considered "low". For instance, this
   // would be `20` for 20%.
@@ -140,24 +138,11 @@
   static bool HasInstance();
   static UserPerformanceTuningManager* GetInstance();
 
-  ~UserPerformanceTuningManager() override;
+  ~UserPerformanceTuningManager();
 
   void AddObserver(Observer* o);
   void RemoveObserver(Observer* o);
 
-  // Returns true if the device is a portable device that can run on battery
-  // power, false otherwise.
-  // This is determined asynchronously, so it may indicate false for an
-  // undetermined amount of time at startup, until the battery state is sampled
-  // for the first time.
-  bool DeviceHasBattery() const;
-
-  // If called with `disabled = true`, will disable battery saver mode until the
-  // device is plugged in or the user configures the battery saver mode state
-  // preference.
-  void SetTemporaryBatterySaverDisabledForSession(bool disabled);
-  bool IsBatterySaverModeDisabledForSession() const;
-
   // Returns true if High Efficiency mode is currently enabled.
   bool IsHighEfficiencyModeActive();
 
@@ -172,6 +157,21 @@
   // Enables high efficiency mode and sets the relevant prefs accordingly.
   void SetHighEfficiencyModeEnabled(bool enabled);
 
+  // Sets the default value of the discard time pref using the command line
+  // switch, if the pref is in the default state.
+  static void SetDefaultTimeBeforeDiscardFromSwitch(PrefService* local_state);
+
+  // Discards the given WebContents with the same mechanism as one that is
+  // discarded through a natural timeout
+  void DiscardPageForTesting(content::WebContents* web_contents);
+
+  // Returns true if the device is a portable device that can run on battery
+  // power, false otherwise.
+  // This is determined asynchronously, so it may indicate false for an
+  // undetermined amount of time at startup, until the battery state is
+  // sampled for the first time.
+  bool DeviceHasBattery() const;
+
   // Returns true if Battery Saver Mode interventions are active. If any state
   // transitions cause an observer notification, this is guaranteed to reflect
   // the *new* value when the observers are notified so the UI layer can make
@@ -188,19 +188,19 @@
   // indicates that the battery state has not been sampled yet.
   int SampledBatteryPercentage() const;
 
-  // Sets the default value of the discard time pref using the command line
-  // switch, if the pref is in the default state.
-  static void SetDefaultTimeBeforeDiscardFromSwitch(PrefService* local_state);
-
-  // Discards the given WebContents with the same mechanism as one that is
-  // discarded through a natural timeout
-  void DiscardPageForTesting(content::WebContents* web_contents);
+  // If called with `disabled = true`, will disable battery saver mode until
+  // the device is plugged in or the user configures the battery saver mode
+  // state preference.
+  void SetTemporaryBatterySaverDisabledForSession(bool disabled);
+  bool IsBatterySaverModeDisabledForSession() const;
 
  private:
   friend class ::ChromeBrowserMainExtraPartsPerformanceManager;
   friend class ::PerformanceManagerMetricsProviderTest;
   friend class UserPerformanceTuningManagerTest;
   friend class TestUserPerformanceTuningManagerEnvironment;
+  friend class ChromeOSBatterySaverProvider;
+  friend class DesktopBatterySaverProvider;
 
   // An implementation of UserPerformanceTuningNotifier::Receiver that
   // forwards the notifications to the UserPerformanceTuningManager on the Main
@@ -223,41 +223,40 @@
       std::unique_ptr<HighEfficiencyModeDelegate>
           high_efficiency_mode_delegate = nullptr);
 
+  class BatterySaverProvider {
+   public:
+    virtual ~BatterySaverProvider() = default;
+
+    virtual bool DeviceHasBattery() const = 0;
+    virtual bool IsBatterySaverActive() const = 0;
+    virtual bool IsUsingBatteryPower() const = 0;
+    virtual base::Time GetLastBatteryUsageTimestamp() const = 0;
+    virtual int SampledBatteryPercentage() const = 0;
+    virtual void SetTemporaryBatterySaverDisabledForSession(bool disabled) = 0;
+    virtual bool IsBatterySaverModeDisabledForSession() const = 0;
+  };
+
   void Start();
 
   void OnHighEfficiencyModePrefChanged();
   void OnHighEfficiencyModeTimeBeforeDiscardChanged();
-  void OnBatterySaverModePrefChanged();
-
-  void UpdateBatterySaverModeState();
 
   void NotifyTabCountThresholdReached();
   void NotifyMemoryThresholdReached();
   void NotifyMemoryMetricsRefreshed();
 
-  // base::PowerStateObserver:
-  void OnPowerStateChange(bool on_battery_power) override;
+  // Called from the installed BatterySaverProvider to signify a change in
+  // battery saver mode related state.
+  void NotifyOnBatterySaverModeChanged(bool battery_saver_mode_enabled);
+  void NotifyOnExternalPowerConnectedChanged(bool on_battery_power);
+  void NotifyOnDeviceHasBatteryChanged(bool has_battery);
+  void NotifyOnBatteryThresholdReached();
 
-  // base::BatteryStateSampler::Observer:
-  void OnBatteryStateSampled(
-      const absl::optional<base::BatteryLevelProvider::BatteryState>&
-          battery_state) override;
-
-  bool was_started_ = false;
-  bool battery_saver_mode_enabled_ = false;
-  bool battery_saver_mode_disabled_for_session_ = false;
   std::unique_ptr<FrameThrottlingDelegate> frame_throttling_delegate_;
   std::unique_ptr<HighEfficiencyModeDelegate> high_efficiency_mode_delegate_;
 
-  bool has_battery_ = false;
-  bool force_has_battery_ = false;
-  bool on_battery_power_ = false;
-  bool is_below_low_battery_threshold_ = false;
-  int battery_percentage_ = -1;
+  std::unique_ptr<BatterySaverProvider> battery_saver_provider_;
 
-  base::ScopedObservation<base::BatteryStateSampler,
-                          base::BatteryStateSampler::Observer>
-      battery_state_sampler_obs_{this};
   PrefChangeRegistrar pref_change_registrar_;
   base::ObserverList<Observer> observers_;
 
diff --git a/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.cc b/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.cc
index a3ced75..2f91dfcb 100644
--- a/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.cc
+++ b/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h"
 
+#include "base/power_monitor/battery_state_sampler.h"
 #include "base/test/power_monitor_test_utils.h"
 #include "chrome/browser/performance_manager/test_support/fake_frame_throttling_delegate.h"
 #include "chrome/browser/performance_manager/test_support/fake_high_efficiency_mode_delegate.h"
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc
index 7275762e..aa61112 100644
--- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc
+++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager.cc
@@ -4,9 +4,13 @@
 
 #include "chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h"
 
+#include "base/check.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/power_monitor/battery_state_sampler.h"
 #include "base/power_monitor/power_monitor.h"
+#include "base/power_monitor/power_observer.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/performance_manager/metrics/page_timeline_monitor.h"
@@ -21,6 +25,11 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/frame_rate_throttling.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chromeos/dbus/power/power_manager_client.h"
+#endif
 
 using performance_manager::user_tuning::prefs::HighEfficiencyModeState;
 using performance_manager::user_tuning::prefs::kHighEfficiencyModeState;
@@ -128,6 +137,276 @@
 
 }  // namespace
 
+class DesktopBatterySaverProvider
+    : public UserPerformanceTuningManager::BatterySaverProvider,
+      public base::PowerStateObserver,
+      public base::BatteryStateSampler::Observer {
+ public:
+  DesktopBatterySaverProvider(UserPerformanceTuningManager* manager,
+                              PrefService* local_state)
+      : manager_(manager) {
+    CHECK(manager_);
+
+    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+    if (command_line->HasSwitch(
+            UserPerformanceTuningManager::kForceDeviceHasBatterySwitch)) {
+      force_has_battery_ = true;
+      has_battery_ = true;
+    }
+
+    pref_change_registrar_.Init(local_state);
+
+    pref_change_registrar_.Add(
+        performance_manager::user_tuning::prefs::kBatterySaverModeState,
+        base::BindRepeating(
+            &DesktopBatterySaverProvider::OnBatterySaverModePrefChanged,
+            base::Unretained(this)));
+
+    on_battery_power_ =
+        base::PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(this);
+
+    base::BatteryStateSampler* battery_state_sampler =
+        base::BatteryStateSampler::Get();
+    // Some platforms don't have a battery sampler, treat them as if they had no
+    // battery at all.
+    if (battery_state_sampler) {
+      battery_state_sampler_obs_.Observe(battery_state_sampler);
+    }
+
+    OnBatterySaverModePrefChanged();
+  }
+
+  ~DesktopBatterySaverProvider() override {
+    base::PowerMonitor::RemovePowerStateObserver(this);
+  }
+
+  // BatterySaverProvider:
+  bool DeviceHasBattery() const override { return has_battery_; }
+  bool IsBatterySaverActive() const override {
+    return battery_saver_mode_enabled_;
+  }
+  bool IsUsingBatteryPower() const override { return on_battery_power_; }
+  base::Time GetLastBatteryUsageTimestamp() const override {
+    return pref_change_registrar_.prefs()->GetTime(
+        performance_manager::user_tuning::prefs::kLastBatteryUseTimestamp);
+  }
+  int SampledBatteryPercentage() const override { return battery_percentage_; }
+  void SetTemporaryBatterySaverDisabledForSession(bool disabled) override {
+    // Setting the temporary mode to its current state is a no-op.
+    if (battery_saver_mode_disabled_for_session_ == disabled) {
+      return;
+    }
+
+    battery_saver_mode_disabled_for_session_ = disabled;
+    UpdateBatterySaverModeState();
+  }
+
+  bool IsBatterySaverModeDisabledForSession() const override {
+    return battery_saver_mode_disabled_for_session_;
+  }
+
+ private:
+  void OnBatterySaverModePrefChanged() {
+    battery_saver_mode_disabled_for_session_ = false;
+    UpdateBatterySaverModeState();
+  }
+
+  void UpdateBatterySaverModeState() {
+    using BatterySaverModeState =
+        performance_manager::user_tuning::prefs::BatterySaverModeState;
+    BatterySaverModeState state = performance_manager::user_tuning::prefs::
+        GetCurrentBatterySaverModeState(pref_change_registrar_.prefs());
+
+    bool previously_enabled = battery_saver_mode_enabled_;
+
+    battery_saver_mode_enabled_ = false;
+
+    if (!battery_saver_mode_disabled_for_session_) {
+      switch (state) {
+        case BatterySaverModeState::kEnabled:
+          battery_saver_mode_enabled_ = true;
+          break;
+        case BatterySaverModeState::kEnabledOnBattery:
+          battery_saver_mode_enabled_ = on_battery_power_;
+          break;
+        case BatterySaverModeState::kEnabledBelowThreshold:
+          battery_saver_mode_enabled_ =
+              on_battery_power_ && is_below_low_battery_threshold_;
+          break;
+        default:
+          battery_saver_mode_enabled_ = false;
+          break;
+      }
+    }
+
+    // Don't change throttling or notify observers if the mode didn't change.
+    if (previously_enabled == battery_saver_mode_enabled_) {
+      return;
+    }
+
+    manager_->NotifyOnBatterySaverModeChanged(battery_saver_mode_enabled_);
+  }
+
+  // base::PowerStateObserver:
+  void OnPowerStateChange(bool on_battery_power) override {
+    on_battery_power_ = on_battery_power;
+
+    // Plugging in the device unsets the temporary disable BSM flag
+    if (!on_battery_power) {
+      battery_saver_mode_disabled_for_session_ = false;
+    }
+
+    manager_->NotifyOnExternalPowerConnectedChanged(on_battery_power);
+
+    UpdateBatterySaverModeState();
+  }
+
+  // base::BatteryStateSampler::Observer:
+  void OnBatteryStateSampled(
+      const absl::optional<base::BatteryLevelProvider::BatteryState>&
+          battery_state) override {
+    if (!battery_state) {
+      return;
+    }
+
+    bool had_battery = has_battery_;
+    has_battery_ = force_has_battery_ || battery_state->battery_count > 0;
+
+    // If the "has battery" state changed, notify observers.
+    if (had_battery != has_battery_) {
+      manager_->NotifyOnDeviceHasBatteryChanged(has_battery_);
+    }
+
+    // Log the unplugged battery usage to local pref if the previous value is
+    // more than a day old.
+    if (has_battery_ && !battery_state->is_external_power_connected &&
+        (base::Time::Now() - GetLastBatteryUsageTimestamp() >
+         kBatteryUsageWriteFrequency)) {
+      pref_change_registrar_.prefs()->SetTime(
+          performance_manager::user_tuning::prefs::kLastBatteryUseTimestamp,
+          base::Time::Now());
+    }
+
+    if (!battery_state->current_capacity ||
+        !battery_state->full_charged_capacity) {
+      // This should only happen if there are no batteries connected, or
+      // multiple batteries connected (in which case their units may not match
+      // so they don't report a charge). We're not under the threshold for any
+      // battery.
+      DCHECK_NE(1, battery_state->battery_count);
+
+      is_below_low_battery_threshold_ = false;
+      return;
+    }
+
+    battery_percentage_ = *(battery_state->full_charged_capacity) > 0
+                              ? *(battery_state->current_capacity) * 100 /
+                                    *(battery_state->full_charged_capacity)
+                              : 100;
+
+    bool was_below_threshold = is_below_low_battery_threshold_;
+
+    // A battery is below the threshold if it's under 20% charge. On some
+    // platforms, we adjust the threshold by a value specified in Finch to
+    // account for the displayed battery level being artificially lower than the
+    // actual level. See
+    // `power_manager::BatteryPercentageConverter::ConvertActualToDisplay`.
+    uint64_t adjusted_low_battery_threshold =
+        UserPerformanceTuningManager::kLowBatteryThresholdPercent +
+        kBatterySaverModeThresholdAdjustmentForDisplayLevel;
+    is_below_low_battery_threshold_ =
+        battery_percentage_ < static_cast<int>(adjusted_low_battery_threshold);
+
+    if (is_below_low_battery_threshold_ && !was_below_threshold) {
+      manager_->NotifyOnBatteryThresholdReached();
+    }
+
+    UpdateBatterySaverModeState();
+  }
+
+  bool battery_saver_mode_enabled_ = false;
+  bool battery_saver_mode_disabled_for_session_ = false;
+
+  bool has_battery_ = false;
+  bool force_has_battery_ = false;
+  bool on_battery_power_ = false;
+  bool is_below_low_battery_threshold_ = false;
+  int battery_percentage_ = -1;
+
+  base::ScopedObservation<base::BatteryStateSampler,
+                          base::BatteryStateSampler::Observer>
+      battery_state_sampler_obs_{this};
+  PrefChangeRegistrar pref_change_registrar_;
+
+  raw_ptr<UserPerformanceTuningManager> manager_;
+};
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+class ChromeOSBatterySaverProvider
+    : public UserPerformanceTuningManager::BatterySaverProvider,
+      public chromeos::PowerManagerClient::Observer {
+ public:
+  explicit ChromeOSBatterySaverProvider(UserPerformanceTuningManager* manager)
+      : manager_(manager) {
+    CHECK(manager_);
+
+    chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
+    CHECK(client);
+
+    power_manager_client_observer_.Observe(client);
+    client->GetBatterySaverModeState(base::BindOnce(
+        &ChromeOSBatterySaverProvider::OnInitialBatterySaverModeObtained,
+        weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  ~ChromeOSBatterySaverProvider() override = default;
+
+  void OnInitialBatterySaverModeObtained(
+      absl::optional<power_manager::BatterySaverModeState> state) {
+    if (state) {
+      BatterySaverModeStateChanged(*state);
+    }
+  }
+
+  // chromeos::PowerManagerClient::Observer:
+  void BatterySaverModeStateChanged(
+      const power_manager::BatterySaverModeState& state) override {
+    if (!state.has_enabled() || enabled_ == state.enabled()) {
+      return;
+    }
+
+    enabled_ = state.enabled();
+
+    manager_->NotifyOnBatterySaverModeChanged(enabled_);
+  }
+
+  // BatterySaverProvider:
+  bool DeviceHasBattery() const override { return false; }
+  bool IsBatterySaverActive() const override { return enabled_; }
+  bool IsUsingBatteryPower() const override { return false; }
+  base::Time GetLastBatteryUsageTimestamp() const override {
+    return base::Time();
+  }
+  int SampledBatteryPercentage() const override { return -1; }
+  void SetTemporaryBatterySaverDisabledForSession(bool disabled) override {
+    NOTREACHED();
+    // No-op when BSM is controlled by the OS
+  }
+  bool IsBatterySaverModeDisabledForSession() const override { return false; }
+
+ private:
+  bool enabled_ = false;
+
+  base::ScopedObservation<chromeos::PowerManagerClient,
+                          chromeos::PowerManagerClient::Observer>
+      power_manager_client_observer_{this};
+
+  raw_ptr<UserPerformanceTuningManager> manager_;
+
+  base::WeakPtrFactory<ChromeOSBatterySaverProvider> weak_ptr_factory_{this};
+};
+#endif
+
 const uint64_t UserPerformanceTuningManager::kLowBatteryThresholdPercent = 20;
 
 const char UserPerformanceTuningManager::kTimeBeforeDiscardInMinutesSwitch[] =
@@ -165,8 +444,6 @@
 UserPerformanceTuningManager::~UserPerformanceTuningManager() {
   DCHECK_EQ(this, g_user_performance_tuning_manager);
   g_user_performance_tuning_manager = nullptr;
-
-  base::PowerMonitor::RemovePowerStateObserver(this);
 }
 
 void UserPerformanceTuningManager::AddObserver(Observer* o) {
@@ -178,22 +455,19 @@
 }
 
 bool UserPerformanceTuningManager::DeviceHasBattery() const {
-  return has_battery_;
+  return battery_saver_provider_ && battery_saver_provider_->DeviceHasBattery();
 }
 
 void UserPerformanceTuningManager::SetTemporaryBatterySaverDisabledForSession(
     bool disabled) {
-  // Setting the temporary mode to its current state is a no-op.
-  if (battery_saver_mode_disabled_for_session_ == disabled)
-    return;
-
-  battery_saver_mode_disabled_for_session_ = disabled;
-  UpdateBatterySaverModeState();
+  CHECK(battery_saver_provider_);
+  battery_saver_provider_->SetTemporaryBatterySaverDisabledForSession(disabled);
 }
 
 bool UserPerformanceTuningManager::IsBatterySaverModeDisabledForSession()
     const {
-  return battery_saver_mode_disabled_for_session_;
+  return battery_saver_provider_ &&
+         battery_saver_provider_->IsBatterySaverModeDisabledForSession();
 }
 
 bool UserPerformanceTuningManager::IsHighEfficiencyModeActive() {
@@ -223,20 +497,25 @@
 }
 
 bool UserPerformanceTuningManager::IsBatterySaverActive() const {
-  return battery_saver_mode_enabled_;
+  return battery_saver_provider_ &&
+         battery_saver_provider_->IsBatterySaverActive();
 }
 
 bool UserPerformanceTuningManager::IsUsingBatteryPower() const {
-  return on_battery_power_;
+  return battery_saver_provider_ &&
+         battery_saver_provider_->IsUsingBatteryPower();
 }
 
 base::Time UserPerformanceTuningManager::GetLastBatteryUsageTimestamp() const {
-  return pref_change_registrar_.prefs()->GetTime(
-      performance_manager::user_tuning::prefs::kLastBatteryUseTimestamp);
+  return battery_saver_provider_
+             ? battery_saver_provider_->GetLastBatteryUsageTimestamp()
+             : base::Time();
 }
 
 int UserPerformanceTuningManager::SampledBatteryPercentage() const {
-  return battery_percentage_;
+  return battery_saver_provider_
+             ? battery_saver_provider_->SampledBatteryPercentage()
+             : -1;
 }
 
 // static
@@ -302,6 +581,37 @@
       }));
 }
 
+void UserPerformanceTuningManager::NotifyOnBatterySaverModeChanged(
+    bool battery_saver_mode_enabled) {
+  if (battery_saver_mode_enabled) {
+    frame_throttling_delegate_->StartThrottlingAllFrameSinks();
+  } else {
+    frame_throttling_delegate_->StopThrottlingAllFrameSinks();
+  }
+
+  for (auto& obs : observers_) {
+    obs.OnBatterySaverModeChanged(battery_saver_mode_enabled);
+  }
+}
+void UserPerformanceTuningManager::NotifyOnExternalPowerConnectedChanged(
+    bool on_battery_power) {
+  for (auto& obs : observers_) {
+    obs.OnExternalPowerConnectedChanged(on_battery_power);
+  }
+}
+
+void UserPerformanceTuningManager::NotifyOnDeviceHasBatteryChanged(
+    bool has_battery) {
+  for (auto& obs : observers_) {
+    obs.OnDeviceHasBatteryChanged(has_battery);
+  }
+}
+void UserPerformanceTuningManager::NotifyOnBatteryThresholdReached() {
+  for (auto& obs : observers_) {
+    obs.OnBatteryThresholdReached();
+  }
+}
+
 UserPerformanceTuningManager::UserPerformanceTuningManager(
     PrefService* local_state,
     std::unique_ptr<UserPerformanceTuningNotifier> notifier,
@@ -332,8 +642,6 @@
 }
 
 void UserPerformanceTuningManager::Start() {
-  was_started_ = true;
-
   pref_change_registrar_.Add(
       performance_manager::user_tuning::prefs::
           kHighEfficiencyModeTimeBeforeDiscardInMinutes,
@@ -354,30 +662,18 @@
   // Make sure the initial state of the pref is passed on to the policy.
   OnHighEfficiencyModePrefChanged();
 
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(kForceDeviceHasBatterySwitch)) {
-    force_has_battery_ = true;
-    has_battery_ = true;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  if (base::FeatureList::IsEnabled(features::kUseDeviceBatterySaverChromeOS)) {
+    battery_saver_provider_ =
+        std::make_unique<ChromeOSBatterySaverProvider>(this);
+  } else {
+    battery_saver_provider_ = std::make_unique<DesktopBatterySaverProvider>(
+        this, pref_change_registrar_.prefs());
   }
-
-  pref_change_registrar_.Add(
-      performance_manager::user_tuning::prefs::kBatterySaverModeState,
-      base::BindRepeating(
-          &UserPerformanceTuningManager::OnBatterySaverModePrefChanged,
-          base::Unretained(this)));
-
-  on_battery_power_ =
-      base::PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(this);
-
-  base::BatteryStateSampler* battery_state_sampler =
-      base::BatteryStateSampler::Get();
-  // Some platforms don't have a battery sampler, treat them as if they had no
-  // battery at all.
-  if (battery_state_sampler) {
-    battery_state_sampler_obs_.Observe(battery_state_sampler);
-  }
-
-  OnBatterySaverModePrefChanged();
+#else
+  battery_saver_provider_ = std::make_unique<DesktopBatterySaverProvider>(
+      this, pref_change_registrar_.prefs());
+#endif
 }
 
 void UserPerformanceTuningManager::OnHighEfficiencyModePrefChanged() {
@@ -397,57 +693,6 @@
   high_efficiency_mode_delegate_->SetTimeBeforeDiscard(time_before_discard);
 }
 
-void UserPerformanceTuningManager::OnBatterySaverModePrefChanged() {
-  battery_saver_mode_disabled_for_session_ = false;
-  UpdateBatterySaverModeState();
-}
-
-void UserPerformanceTuningManager::UpdateBatterySaverModeState() {
-  DCHECK(was_started_);
-
-  using BatterySaverModeState =
-      performance_manager::user_tuning::prefs::BatterySaverModeState;
-  performance_manager::user_tuning::prefs::BatterySaverModeState state =
-      performance_manager::user_tuning::prefs::GetCurrentBatterySaverModeState(
-          pref_change_registrar_.prefs());
-
-  bool previously_enabled = battery_saver_mode_enabled_;
-
-  battery_saver_mode_enabled_ = false;
-
-  if (!battery_saver_mode_disabled_for_session_) {
-    switch (state) {
-      case BatterySaverModeState::kEnabled:
-        battery_saver_mode_enabled_ = true;
-        break;
-      case BatterySaverModeState::kEnabledOnBattery:
-        battery_saver_mode_enabled_ = on_battery_power_;
-        break;
-      case BatterySaverModeState::kEnabledBelowThreshold:
-        battery_saver_mode_enabled_ =
-            on_battery_power_ && is_below_low_battery_threshold_;
-        break;
-      default:
-        battery_saver_mode_enabled_ = false;
-        break;
-    }
-  }
-
-  // Don't change throttling or notify observers if the mode didn't change.
-  if (previously_enabled == battery_saver_mode_enabled_)
-    return;
-
-  if (battery_saver_mode_enabled_) {
-    frame_throttling_delegate_->StartThrottlingAllFrameSinks();
-  } else {
-    frame_throttling_delegate_->StopThrottlingAllFrameSinks();
-  }
-
-  for (auto& obs : observers_) {
-    obs.OnBatterySaverModeChanged(battery_saver_mode_enabled_);
-  }
-}
-
 void UserPerformanceTuningManager::NotifyTabCountThresholdReached() {
   for (auto& obs : observers_) {
     obs.OnTabCountThresholdReached();
@@ -466,85 +711,6 @@
   }
 }
 
-void UserPerformanceTuningManager::OnPowerStateChange(bool on_battery_power) {
-  on_battery_power_ = on_battery_power;
-
-  // Plugging in the device unsets the temporary disable BSM flag
-  if (!on_battery_power) {
-    battery_saver_mode_disabled_for_session_ = false;
-  }
-
-  for (auto& obs : observers_) {
-    obs.OnExternalPowerConnectedChanged(on_battery_power);
-  }
-
-  UpdateBatterySaverModeState();
-}
-
-void UserPerformanceTuningManager::OnBatteryStateSampled(
-    const absl::optional<base::BatteryLevelProvider::BatteryState>&
-        battery_state) {
-  if (!battery_state)
-    return;
-
-  bool had_battery = has_battery_;
-  has_battery_ = force_has_battery_ || battery_state->battery_count > 0;
-
-  // If the "has battery" state changed, notify observers.
-  if (had_battery != has_battery_) {
-    for (auto& obs : observers_) {
-      obs.OnDeviceHasBatteryChanged(has_battery_);
-    }
-  }
-
-  // Log the unplugged battery usage to local pref if the previous value is more
-  // than a day old.
-  if (has_battery_ && !battery_state->is_external_power_connected &&
-      (base::Time::Now() - GetLastBatteryUsageTimestamp() >
-       kBatteryUsageWriteFrequency)) {
-    pref_change_registrar_.prefs()->SetTime(
-        performance_manager::user_tuning::prefs::kLastBatteryUseTimestamp,
-        base::Time::Now());
-  }
-
-  if (!battery_state->current_capacity ||
-      !battery_state->full_charged_capacity) {
-    // This should only happen if there are no batteries connected, or multiple
-    // batteries connected (in which case their units may not match so they
-    // don't report a charge). We're not under the threshold for any battery.
-    DCHECK_NE(1, battery_state->battery_count);
-
-    is_below_low_battery_threshold_ = false;
-    return;
-  }
-
-  battery_percentage_ = *(battery_state->full_charged_capacity) > 0
-                            ? *(battery_state->current_capacity) * 100 /
-                                  *(battery_state->full_charged_capacity)
-                            : 100;
-
-  bool was_below_threshold = is_below_low_battery_threshold_;
-
-  // A battery is below the threshold if it's under 20% charge. On some
-  // platforms, we adjust the threshold by a value specified in Finch to account
-  // for the displayed battery level being artificially lower than the actual
-  // level. See
-  // `power_manager::BatteryPercentageConverter::ConvertActualToDisplay`.
-  uint64_t adjusted_low_battery_threshold =
-      kLowBatteryThresholdPercent +
-      kBatterySaverModeThresholdAdjustmentForDisplayLevel;
-  is_below_low_battery_threshold_ =
-      battery_percentage_ < static_cast<int>(adjusted_low_battery_threshold);
-
-  if (is_below_low_battery_threshold_ && !was_below_threshold) {
-    for (auto& obs : observers_) {
-      obs.OnBatteryThresholdReached();
-    }
-  }
-
-  UpdateBatterySaverModeState();
-}
-
 void UserPerformanceTuningManager::DiscardPageForTesting(
     content::WebContents* web_contents) {
   base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
index 08c862a..5fc0d4fb 100644
--- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
+++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h"
 
 #include "base/memory/raw_ptr.h"
+#include "base/power_monitor/battery_state_sampler.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_source.h"
 #include "base/run_loop.h"
@@ -20,6 +21,13 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chromeos/dbus/power/power_manager_client.h"
+#include "dbus/mock_bus.h"
+#include "dbus/mock_object_proxy.h"
+#include "dbus/object_path.h"
+#endif
+
 namespace performance_manager::user_tuning {
 namespace {
 
@@ -78,6 +86,19 @@
       .capture_time = base::TimeTicks::Now()};
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+class ScopedFakePowerManagerClientLifetime {
+ public:
+  ScopedFakePowerManagerClientLifetime() {
+    chromeos::PowerManagerClient::InitializeFake();
+  }
+
+  ~ScopedFakePowerManagerClientLifetime() {
+    chromeos::PowerManagerClient::Shutdown();
+  }
+};
+#endif
+
 }  // namespace
 
 class UserPerformanceTuningManagerTest : public testing::Test {
@@ -131,6 +152,9 @@
   raw_ptr<FakeHighEfficiencyModeDelegate> high_efficiency_mode_delegate_;
   std::unique_ptr<base::BatteryStateSampler> battery_sampler_;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  ScopedFakePowerManagerClientLifetime fake_power_manager_client_lifetime_;
+#endif
   raw_ptr<FakePowerMonitorSource> power_monitor_source_;
   bool throttling_enabled_ = false;
   std::unique_ptr<UserPerformanceTuningManager> manager_;
@@ -487,4 +511,59 @@
   EXPECT_EQ(100, manager()->SampledBatteryPercentage());
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(UserPerformanceTuningManagerTest, ManagedFromPowerManager) {
+  base::test::ScopedFeatureList feature_list_;
+  feature_list_.InitAndEnableFeature(
+      performance_manager::features::kUseDeviceBatterySaverChromeOS);
+
+  StartManager();
+  EXPECT_FALSE(manager()->IsBatterySaverActive());
+  EXPECT_FALSE(throttling_enabled());
+
+  base::RunLoop run_loop;
+  std::unique_ptr<QuitRunLoopOnBSMChangeObserver> observer =
+      std::make_unique<QuitRunLoopOnBSMChangeObserver>(run_loop.QuitClosure());
+  manager()->AddObserver(observer.get());
+
+  // Request to enable PowerManager's BSM
+  power_manager::SetBatterySaverModeStateRequest proto;
+  proto.set_enabled(true);
+  chromeos::PowerManagerClient::Get()->SetBatterySaverModeState(proto);
+
+  run_loop.Run();
+  manager()->RemoveObserver(observer.get());
+
+  EXPECT_TRUE(manager()->IsBatterySaverActive());
+  EXPECT_TRUE(throttling_enabled());
+}
+
+TEST_F(UserPerformanceTuningManagerTest,
+       StartsEnabledIfAlreadyEnabledInPowerManager) {
+  base::test::ScopedFeatureList feature_list_;
+  feature_list_.InitAndEnableFeature(
+      performance_manager::features::kUseDeviceBatterySaverChromeOS);
+
+  // Request to enable PowerManager's BSM
+  power_manager::SetBatterySaverModeStateRequest proto;
+  proto.set_enabled(true);
+  chromeos::PowerManagerClient::Get()->SetBatterySaverModeState(proto);
+
+  StartManager();
+
+  // It's fine to install the observer after the manager is created, as long as
+  // it's done before the runloop runs
+  base::RunLoop run_loop;
+  std::unique_ptr<QuitRunLoopOnBSMChangeObserver> observer =
+      std::make_unique<QuitRunLoopOnBSMChangeObserver>(run_loop.QuitClosure());
+  manager()->AddObserver(observer.get());
+
+  run_loop.Run();
+  manager()->RemoveObserver(observer.get());
+
+  EXPECT_TRUE(manager()->IsBatterySaverActive());
+  EXPECT_TRUE(throttling_enabled());
+}
+#endif
+
 }  // namespace performance_manager::user_tuning
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index 1056f3d9..fa21e9d 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -106,7 +106,7 @@
     public static final String BOOKMARKS_LAST_USED_URL = "enhanced_bookmark_last_used_url";
     public static final String BOOKMARKS_LAST_USED_PARENT =
             "enhanced_bookmark_last_used_parent_folder";
-    public static final String BOOKMARK_VISUALS_PREF = "Chrome.Bookmarks.BookmarkRowDisplay";
+    public static final String BOOKMARKS_VISUALS_PREF = "Chrome.Bookmarks.BookmarkRowDisplay";
 
     /**
      * Whether Chrome is set as the default browser.
@@ -999,7 +999,7 @@
                 APP_LAUNCH_SEARCH_ENGINE_HAD_LOGO,
                 APPLICATION_OVERRIDE_LANGUAGE,
                 BLUETOOTH_NOTIFICATION_IDS,
-                BOOKMARK_VISUALS_PREF,
+                BOOKMARKS_VISUALS_PREF,
                 CHROME_SURVEY_DOWNLOAD_ATTEMPTS.pattern(),
                 CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.pattern(),
                 CLIPBOARD_SHARED_URI,
diff --git a/chrome/browser/preloading/preloading_features.cc b/chrome/browser/preloading/preloading_features.cc
index dd9f12d7..1684cd4c 100644
--- a/chrome/browser/preloading/preloading_features.cc
+++ b/chrome/browser/preloading/preloading_features.cc
@@ -11,6 +11,6 @@
 // preloading, and extended preloading.
 BASE_FEATURE(kPreloadingDesktopSettingsSubPage,
              "PreloadingDesktopSettingsSubPage",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 }  // namespace features
diff --git a/chrome/browser/printing/print_preview_context_menu_observer.cc b/chrome/browser/printing/print_preview_context_menu_observer.cc
index f3ec26d..583a93c 100644
--- a/chrome/browser/printing/print_preview_context_menu_observer.cc
+++ b/chrome/browser/printing/print_preview_context_menu_observer.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/printing/print_preview_context_menu_observer.h"
 
+#include "base/check.h"
 #include "base/notreached.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
@@ -16,11 +17,9 @@
 }
 
 bool PrintPreviewContextMenuObserver::IsPrintPreviewDialog() {
-  printing::PrintPreviewDialogController* controller =
-      printing::PrintPreviewDialogController::GetInstance();
-  if (!controller)
-    return false;
-  return (controller->GetPrintPreviewForContents(contents_) != nullptr);
+  auto* controller = printing::PrintPreviewDialogController::GetInstance();
+  CHECK(controller);
+  return !!controller->GetPrintPreviewForContents(contents_);
 }
 
 bool PrintPreviewContextMenuObserver::IsCommandIdSupported(int command_id) {
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index d42b14f..6aced40d 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -214,7 +214,6 @@
 #if BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/android/explore_sites/explore_sites_service_factory.h"
 #include "chrome/browser/android/reading_list/reading_list_manager_factory.h"
-#include "chrome/browser/android/reading_list/reading_list_notification_service_factory.h"
 #include "chrome/browser/android/search_permissions/search_permissions_service.h"
 #include "chrome/browser/android/thin_webview/chrome_thin_webview_initializer.h"
 #include "chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_factory.h"
@@ -888,10 +887,6 @@
   ProtocolHandlerRegistryFactory::GetInstance();
 
   ReadingListModelFactory::GetInstance();
-#if BUILDFLAG(IS_ANDROID)
-  ReadingListManagerFactory::GetInstance();
-  ReadingListNotificationServiceFactory::GetInstance();
-#endif
 #if !BUILDFLAG(IS_ANDROID)
   RecipesServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/reading_list/android/BUILD.gn b/chrome/browser/reading_list/android/BUILD.gn
index 7f1ed9d..052661a 100644
--- a/chrome/browser/reading_list/android/BUILD.gn
+++ b/chrome/browser/reading_list/android/BUILD.gn
@@ -15,11 +15,6 @@
     "reading_list_manager.h",
     "reading_list_manager_impl.cc",
     "reading_list_manager_impl.h",
-    "reading_list_notification_client.cc",
-    "reading_list_notification_client.h",
-    "reading_list_notification_delegate.h",
-    "reading_list_notification_service.cc",
-    "reading_list_notification_service.h",
   ]
 
   # This target should not depend on the whole //chrome/browser target.
@@ -39,11 +34,7 @@
 
 source_set("unit_tests") {
   testonly = true
-  sources = [
-    "reading_list_manager_impl_unittest.cc",
-    "reading_list_notification_client_unittest.cc",
-    "reading_list_notification_service_unittest.cc",
-  ]
+  sources = [ "reading_list_manager_impl_unittest.cc" ]
   deps = [
     ":android",
     "//base/test:test_support",
diff --git a/chrome/browser/reading_list/android/reading_list_notification_client.cc b/chrome/browser/reading_list/android/reading_list_notification_client.cc
deleted file mode 100644
index 38607c4..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_client.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/reading_list/android/reading_list_notification_client.h"
-
-#include <ostream>
-
-#include "chrome/browser/notifications/scheduler/public/notification_scheduler_types.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-
-using ThrottleConfigCallback =
-    notifications::NotificationSchedulerClient::ThrottleConfigCallback;
-
-ReadingListNotificationClient::ReadingListNotificationClient(
-    ServiceGetter getter)
-    : service_getter_(getter) {}
-
-ReadingListNotificationClient::~ReadingListNotificationClient() = default;
-
-void ReadingListNotificationClient::BeforeShowNotification(
-    std::unique_ptr<notifications::NotificationData> notification_data,
-    NotificationDataCallback callback) {
-  DCHECK(notification_data.get());
-  GetNotificationService()->BeforeShowNotification(std::move(notification_data),
-                                                   std::move(callback));
-}
-
-void ReadingListNotificationClient::OnSchedulerInitialized(
-    bool success,
-    std::set<std::string> guids) {
-  DCHECK_LE(guids.size(), 1u)
-      << "Only should have at most one reading list notification.";
-}
-
-void ReadingListNotificationClient::OnUserAction(
-    const notifications::UserActionData& action_data) {
-  if (action_data.action_type == notifications::UserActionType::kClick) {
-    GetNotificationService()->OnClick();
-  }
-}
-
-void ReadingListNotificationClient::GetThrottleConfig(
-    ThrottleConfigCallback callback) {
-  // No throttle.
-  std::move(callback).Run(nullptr);
-}
-
-ReadingListNotificationService*
-ReadingListNotificationClient::GetNotificationService() {
-  return service_getter_.Run();
-}
diff --git a/chrome/browser/reading_list/android/reading_list_notification_client.h b/chrome/browser/reading_list/android/reading_list_notification_client.h
deleted file mode 100644
index 654b108..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_client.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_CLIENT_H_
-#define CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_CLIENT_H_
-
-#include <memory>
-#include <set>
-
-#include "chrome/browser/notifications/scheduler/public/notification_scheduler_client.h"
-
-namespace notifications {
-struct NotificationData;
-struct UserActionData;
-}  // namespace notifications
-
-class ReadingListNotificationService;
-
-// The client interface that communicates with notification scheduling system.
-class ReadingListNotificationClient
-    : public notifications::NotificationSchedulerClient {
- public:
-  using ServiceGetter =
-      base::RepeatingCallback<ReadingListNotificationService*()>;
-  explicit ReadingListNotificationClient(ServiceGetter getter);
-  ~ReadingListNotificationClient() override;
-  ReadingListNotificationClient(const ReadingListNotificationClient&) = delete;
-  ReadingListNotificationClient operator=(
-      const ReadingListNotificationClient&) = delete;
-
-  // notifications::NotificationSchedulerClient implementation.
-  void BeforeShowNotification(
-      std::unique_ptr<notifications::NotificationData> notification_data,
-      NotificationDataCallback callback) override;
-  void OnSchedulerInitialized(bool success,
-                              std::set<std::string> guids) override;
-  void OnUserAction(const notifications::UserActionData& action_data) override;
-  void GetThrottleConfig(
-      notifications::NotificationSchedulerClient::ThrottleConfigCallback
-          callback) override;
-
- private:
-  ReadingListNotificationService* GetNotificationService();
-
-  ServiceGetter service_getter_;
-};
-
-#endif  // CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_CLIENT_H_
diff --git a/chrome/browser/reading_list/android/reading_list_notification_client_unittest.cc b/chrome/browser/reading_list/android/reading_list_notification_client_unittest.cc
deleted file mode 100644
index c40e6c33..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_client_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/reading_list/android/reading_list_notification_client.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/run_loop.h"
-#include "base/test/bind.h"
-#include "base/test/task_environment.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using NotificationDataCallback =
-    ReadingListNotificationService::NotificationDataCallback;
-using ThrottleConfigCallback =
-    notifications::NotificationSchedulerClient::ThrottleConfigCallback;
-using testing::_;
-
-namespace {
-
-constexpr notifications::SchedulerClientType kNotificationType =
-    notifications::SchedulerClientType::kReadingList;
-
-class MockReadingListNotificationService
-    : public ReadingListNotificationService {
- public:
-  MockReadingListNotificationService() = default;
-  ~MockReadingListNotificationService() override = default;
-  MOCK_METHOD(void, OnStart, (), (override));
-  MOCK_METHOD(void,
-              BeforeShowNotification,
-              (std::unique_ptr<notifications::NotificationData>,
-               NotificationDataCallback),
-              (override));
-  MOCK_METHOD(void, OnClick, (), (override));
-};
-
-class ReadingListNotificationClientTest : public testing::Test {
- public:
-  ReadingListNotificationClientTest() = default;
-  ~ReadingListNotificationClientTest() override = default;
-
-  void SetUp() override {
-    auto service_getter = base::BindLambdaForTesting([&]() {
-      return static_cast<ReadingListNotificationService*>(&mock_service_);
-    });
-    client_ = std::make_unique<ReadingListNotificationClient>(service_getter);
-  }
-
- protected:
-  ReadingListNotificationClient* client() { return client_.get(); }
-  MockReadingListNotificationService* mock_service() { return &mock_service_; }
-
- private:
-  base::test::TaskEnvironment task_environment_;
-  MockReadingListNotificationService mock_service_;
-  std::unique_ptr<ReadingListNotificationClient> client_;
-};
-
-TEST_F(ReadingListNotificationClientTest, BeforeShowNotification) {
-  EXPECT_CALL(*mock_service(), BeforeShowNotification(_, _));
-  client()->BeforeShowNotification(
-      std::make_unique<notifications::NotificationData>(),
-      NotificationDataCallback());
-}
-
-TEST_F(ReadingListNotificationClientTest, OnSchedulerInitialized) {
-  client()->OnSchedulerInitialized(true, std::set<std::string>());
-}
-
-TEST_F(ReadingListNotificationClientTest, OnUserAction) {
-  EXPECT_CALL(*mock_service(), OnClick());
-  notifications::UserActionData action(
-      kNotificationType, notifications::UserActionType::kClick, "1234");
-  client()->OnUserAction(action);
-}
-
-TEST_F(ReadingListNotificationClientTest, GetThrottleConfig) {
-  base::RunLoop loop;
-  auto callback = base::BindLambdaForTesting(
-      [&](std::unique_ptr<notifications::ThrottleConfig> config) {
-        EXPECT_EQ(nullptr, config);
-        loop.Quit();
-      });
-  client()->GetThrottleConfig(callback);
-  loop.Run();
-}
-
-}  // namespace
diff --git a/chrome/browser/reading_list/android/reading_list_notification_delegate.h b/chrome/browser/reading_list/android/reading_list_notification_delegate.h
deleted file mode 100644
index 3f456d9..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_delegate.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_DELEGATE_H_
-#define CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_DELEGATE_H_
-
-#include <string>
-
-
-class ReadingListNotificationDelegate {
- public:
-  ReadingListNotificationDelegate() = default;
-  virtual ~ReadingListNotificationDelegate() = default;
-
-  ReadingListNotificationDelegate(const ReadingListNotificationDelegate&) =
-      delete;
-  ReadingListNotificationDelegate& operator=(
-      const ReadingListNotificationDelegate&) = delete;
-
-  // Gets the weekly notification title.
-  virtual std::u16string getNotificationTitle() = 0;
-
-  // Gets the weekly notification subtitle.
-  virtual std::u16string getNotificationSubTitle(int unread_size) = 0;
-
-  // Opens the reading list UI.
-  virtual void OpenReadingListPage() = 0;
-};
-
-#endif  // CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_DELEGATE_H_
diff --git a/chrome/browser/reading_list/android/reading_list_notification_service.cc b/chrome/browser/reading_list/android/reading_list_notification_service.cc
deleted file mode 100644
index 04d432d..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_service.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-
-#include "base/feature_list.h"
-#include "base/time/time.h"
-#include "chrome/browser/notifications/scheduler/public/client_overview.h"
-#include "chrome/browser/notifications/scheduler/public/notification_data.h"
-#include "chrome/browser/notifications/scheduler/public/notification_params.h"
-#include "chrome/browser/notifications/scheduler/public/notification_schedule_service.h"
-#include "chrome/browser/notifications/scheduler/public/notification_scheduler_types.h"
-#include "chrome/browser/notifications/scheduler/public/schedule_params.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_delegate.h"
-#include "components/reading_list/core/reading_list_model.h"
-#include "components/reading_list/features/reading_list_switches.h"
-
-constexpr notifications::SchedulerClientType kNotificationType =
-    notifications::SchedulerClientType::kReadingList;
-const base::TimeDelta kDeliverStartTimeDelta = base::Days(7);
-const base::TimeDelta kDeliverEndTimeDelta = base::Minutes(5);
-
-ReadingListNotificationService::Config::Config() = default;
-ReadingListNotificationService::Config::~Config() = default;
-
-// static
-bool ReadingListNotificationService::IsEnabled() {
-  return base::FeatureList::IsEnabled(
-      reading_list::switches::kReadLaterReminderNotification);
-}
-
-ReadingListNotificationServiceImpl::ReadingListNotificationServiceImpl(
-    ReadingListModel* reading_list_model,
-    notifications::NotificationScheduleService* notification_scheduler,
-    std::unique_ptr<ReadingListNotificationDelegate> delegate,
-    std::unique_ptr<Config> config,
-    base::Clock* clock)
-    : reading_list_model_(reading_list_model),
-      notification_scheduler_(notification_scheduler),
-      delegate_(std::move(delegate)),
-      config_(std::move(config)),
-      clock_(clock) {
-  DCHECK(notification_scheduler_);
-  DCHECK(reading_list_model_);
-  reading_list_model_->AddObserver(this);
-}
-
-ReadingListNotificationServiceImpl::~ReadingListNotificationServiceImpl() {
-  reading_list_model_->RemoveObserver(this);
-}
-
-void ReadingListNotificationServiceImpl::OnStart() {
-  if (!reading_list_model_->loaded()) {
-    CallWhenModelLoaded(
-        base::BindOnce(&ReadingListNotificationServiceImpl::OnStart,
-                       weak_ptr_factory_.GetWeakPtr()));
-    return;
-  }
-
-  // Delete notification if there is no unread pages.
-  size_t unread_size = ReadingListUnreadSize();
-  if (unread_size == 0u) {
-    notification_scheduler_->DeleteNotifications(kNotificationType);
-    return;
-  }
-
-  MaybeScheduleNotification();
-}
-
-void ReadingListNotificationServiceImpl::BeforeShowNotification(
-    std::unique_ptr<notifications::NotificationData> notification_data,
-    NotificationDataCallback callback) {
-  if (!reading_list_model_->loaded()) {
-    CallWhenModelLoaded(base::BindOnce(
-        &ReadingListNotificationServiceImpl::BeforeShowNotification,
-        weak_ptr_factory_.GetWeakPtr(), std::move(notification_data),
-        std::move(callback)));
-    return;
-  }
-
-  // Cancel the notification before rendering in tray if no reading list
-  // articles.
-  size_t unread_size = ReadingListUnreadSize();
-  if (unread_size == 0u) {
-    std::move(callback).Run(nullptr);
-    notification_scheduler_->DeleteNotifications(kNotificationType);
-    return;
-  }
-
-  // Update the unread page count text.
-  notification_data->message = delegate_->getNotificationSubTitle(unread_size);
-  std::move(callback).Run(std::move(notification_data));
-
-  // Schedule another one.
-  MaybeScheduleNotification();
-}
-
-void ReadingListNotificationServiceImpl::OnClick() {
-  delegate_->OpenReadingListPage();
-}
-
-void ReadingListNotificationServiceImpl::ReadingListModelLoaded(
-    const ReadingListModel* model) {
-  // Flush cached closures.
-  while (!cached_closures_.empty()) {
-    auto closure = std::move(cached_closures_.front());
-    cached_closures_.pop();
-    std::move(closure).Run();
-  }
-}
-
-std::queue<base::OnceClosure>*
-ReadingListNotificationServiceImpl::GetCachedClosureForTesting() {
-  return &cached_closures_;
-}
-
-void ReadingListNotificationServiceImpl::CallWhenModelLoaded(
-    base::OnceClosure closure) {
-  if (reading_list_model_->loaded()) {
-    std::move(closure).Run();
-    return;
-  }
-
-  cached_closures_.emplace(std::move(closure));
-}
-
-void ReadingListNotificationServiceImpl::MaybeScheduleNotification() {
-  notification_scheduler_->GetClientOverview(
-      kNotificationType,
-      base::BindOnce(&ReadingListNotificationServiceImpl::OnClientOverview,
-                     weak_ptr_factory_.GetWeakPtr(), ReadingListUnreadSize()));
-}
-
-void ReadingListNotificationServiceImpl::OnClientOverview(
-    size_t unread_size,
-    notifications::ClientOverview overview) {
-  // Already scheduled a weekly notification, do nothing.
-  if (overview.num_scheduled_notifications > 0u)
-    return;
-
-  ScheduleNotification(unread_size);
-}
-
-void ReadingListNotificationServiceImpl::ScheduleNotification(int unread_size) {
-  DCHECK_GT(unread_size, 0);
-  notifications::NotificationData data;
-  data.title = delegate_->getNotificationTitle();
-  data.message = delegate_->getNotificationSubTitle(unread_size);
-  notifications::ScheduleParams schedule_params;
-  schedule_params.priority =
-      notifications::ScheduleParams::Priority::kNoThrottle;
-
-  // Show after a week.
-  schedule_params.deliver_time_start = GetShowTime();
-  schedule_params.deliver_time_end =
-      schedule_params.deliver_time_start.value() + kDeliverEndTimeDelta;
-
-  auto params = std::make_unique<notifications::NotificationParams>(
-      kNotificationType, std::move(data), std::move(schedule_params));
-  notification_scheduler_->Schedule(std::move(params));
-}
-
-size_t ReadingListNotificationServiceImpl::ReadingListUnreadSize() {
-  DCHECK(reading_list_model_->loaded());
-  return reading_list_model_->unread_size();
-}
-
-base::Time ReadingListNotificationServiceImpl::GetShowTime() const {
-  base::Time time = clock_->Now() + kDeliverStartTimeDelta;
-  base::Time::Exploded exploded;
-  time.LocalExplode(&exploded);
-
-  exploded.hour = config_->notification_show_time;
-  exploded.minute = 0;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-
-  bool success = base::Time::FromLocalExploded(exploded, &time);
-  DCHECK(success);
-  return time;
-}
diff --git a/chrome/browser/reading_list/android/reading_list_notification_service.h b/chrome/browser/reading_list/android/reading_list_notification_service.h
deleted file mode 100644
index 178e4a29..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_service.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_SERVICE_H_
-#define CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_SERVICE_H_
-
-#include <memory>
-#include <queue>
-
-#include "base/functional/callback.h"
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/clock.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/reading_list/core/reading_list_model_observer.h"
-
-namespace notifications {
-class NotificationScheduleService;
-struct ClientOverview;
-struct NotificationData;
-}  // namespace notifications
-
-class ReadingListModel;
-class ReadingListNotificationDelegate;
-
-// Handles reading list weekly notification logic.
-class ReadingListNotificationService : public KeyedService {
- public:
-  using NotificationDataCallback = base::OnceCallback<void(
-      std::unique_ptr<notifications::NotificationData>)>;
-
-  // Configuration related to the reading list notification.
-  struct Config {
-    Config();
-    ~Config();
-
-    // Local time that the weekly notification will be triggered.
-    int notification_show_time = 8;
-  };
-
-  // Returns whether the reading list notification is enabled.
-  static bool IsEnabled();
-
-  ReadingListNotificationService() = default;
-  ~ReadingListNotificationService() override = default;
-  ReadingListNotificationService(const ReadingListNotificationService&) =
-      delete;
-  ReadingListNotificationService& operator=(
-      const ReadingListNotificationService&) = delete;
-
-  // Called when Chrome starts.
-  virtual void OnStart() = 0;
-
-  // Called before the notification is shown. Update the number of unread pages.
-  virtual void BeforeShowNotification(
-      std::unique_ptr<notifications::NotificationData> notification_data,
-      NotificationDataCallback callback) = 0;
-
-  // Called when the notification is clicked.
-  virtual void OnClick() = 0;
-};
-
-// Implementation of ReadingListNotificationService.
-class ReadingListNotificationServiceImpl
-    : public ReadingListNotificationService,
-      public ReadingListModelObserver {
- public:
-  ReadingListNotificationServiceImpl(
-      ReadingListModel* reading_list_model,
-      notifications::NotificationScheduleService* notification_scheduler,
-      std::unique_ptr<ReadingListNotificationDelegate> delegate,
-      std::unique_ptr<Config> config,
-      base::Clock* clock);
-  ~ReadingListNotificationServiceImpl() override;
-
-  // ReadingListNotificationService implementation.
-  void OnStart() override;
-  void BeforeShowNotification(
-      std::unique_ptr<notifications::NotificationData> notification_data,
-      NotificationDataCallback callback) override;
-  void OnClick() override;
-
-  // ReadingListModelObserver implementation.
-  void ReadingListModelLoaded(const ReadingListModel* model) override;
-
-  std::queue<base::OnceClosure>* GetCachedClosureForTesting();
-
- private:
-  // Calls the |closure| right away or waits for |reading_list_model_| loaded.
-  void CallWhenModelLoaded(base::OnceClosure closure);
-
-  // Schedules the weekly notification that shows the total number of unread
-  // pages.
-  void MaybeScheduleNotification();
-  void OnClientOverview(size_t unread_count,
-                        notifications::ClientOverview overview);
-  void ScheduleNotification(int unread_count);
-
-  // Gets the number of unread reading list articles.
-  size_t ReadingListUnreadSize();
-
-  // Gets the next notification show time.
-  base::Time GetShowTime() const;
-
-  raw_ptr<ReadingListModel> reading_list_model_;
-  raw_ptr<notifications::NotificationScheduleService> notification_scheduler_;
-  std::unique_ptr<ReadingListNotificationDelegate> delegate_;
-
-  // Closures cached by MaybeCallSoon().
-  std::queue<base::OnceClosure> cached_closures_;
-  std::unique_ptr<Config> config_;
-  raw_ptr<base::Clock> clock_;
-
-  base::WeakPtrFactory<ReadingListNotificationServiceImpl> weak_ptr_factory_{
-      this};
-};
-
-#endif  // CHROME_BROWSER_READING_LIST_ANDROID_READING_LIST_NOTIFICATION_SERVICE_H_
diff --git a/chrome/browser/reading_list/android/reading_list_notification_service_unittest.cc b/chrome/browser/reading_list/android/reading_list_notification_service_unittest.cc
deleted file mode 100644
index 2626a90..0000000
--- a/chrome/browser/reading_list/android/reading_list_notification_service_unittest.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/reading_list/android/reading_list_notification_service.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/memory/raw_ptr.h"
-#include "base/run_loop.h"
-#include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_clock.h"
-#include "base/test/task_environment.h"
-#include "base/time/time.h"
-#include "chrome/browser/notifications/scheduler/test/mock_notification_schedule_service.h"
-#include "chrome/browser/reading_list/android/reading_list_notification_delegate.h"
-#include "components/reading_list/core/fake_reading_list_model_storage.h"
-#include "components/reading_list/core/reading_list_model_impl.h"
-#include "components/reading_list/features/reading_list_switches.h"
-#include "components/sync/base/storage_type.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using notifications::ClientOverview;
-using notifications::SchedulerClientType;
-using notifications::test::MockNotificationScheduleService;
-using reading_list::switches::kReadLaterReminderNotification;
-using testing::_;
-using testing::Invoke;
-
-namespace {
-
-constexpr notifications::SchedulerClientType kNotificationType =
-    notifications::SchedulerClientType::kReadingList;
-const char kNow[] = "10 Feb 2020 01:00:00";
-const char kShowTime[] = "17 Feb 2020 08:00:00";
-
-MATCHER_P(DeliverOnTime, time, "") {
-  return time == arg->schedule_params.deliver_time_start.value();
-}
-
-class MockDelegate : public ReadingListNotificationDelegate {
- public:
-  MockDelegate() = default;
-  ~MockDelegate() override = default;
-  MOCK_METHOD(std::u16string, getNotificationTitle, (), (override));
-  MOCK_METHOD(std::u16string, getNotificationSubTitle, (int), (override));
-  MOCK_METHOD(void, OpenReadingListPage, (), (override));
-};
-
-class ReadingListNotificationServiceTest : public testing::Test {
- public:
-  ReadingListNotificationServiceTest() = default;
-  ~ReadingListNotificationServiceTest() override = default;
-
-  void SetUp() override {
-    clock_.SetNow(MakeLocalTime(kNow));
-    auto storage = std::make_unique<FakeReadingListModelStorage>();
-    base::WeakPtr<FakeReadingListModelStorage> storage_ptr =
-        storage->AsWeakPtr();
-    reading_list_model_ = std::make_unique<ReadingListModelImpl>(
-        std::move(storage), syncer::StorageType::kUnspecified, &clock_);
-    // Complete the initial model load from storage.
-    storage_ptr->TriggerLoadCompletion();
-
-    auto delegate = std::make_unique<MockDelegate>();
-    delegate_ = delegate.get();
-    auto config = std::make_unique<ReadingListNotificationService::Config>();
-    config->notification_show_time = 8;
-    service_ = std::make_unique<ReadingListNotificationServiceImpl>(
-        reading_list_model_.get(), &mock_schedule_service_, std::move(delegate),
-        std::move(config), &clock_);
-  }
-
- protected:
-  base::test::TaskEnvironment* task_environment() { return &task_environment_; }
-  ReadingListNotificationServiceImpl* service() { return service_.get(); }
-  MockDelegate* delegate() { return delegate_; }
-  base::SimpleTestClock* clock() { return &clock_; }
-  MockNotificationScheduleService* mock_schedule_service() {
-    return &mock_schedule_service_;
-  }
-  ReadingListModelImpl* reading_list_model() {
-    return reading_list_model_.get();
-  }
-
-  base::Time MakeLocalTime(const char* time_str) {
-    base::Time time;
-    EXPECT_TRUE(base::Time::FromString(time_str, &time));
-    return time;
-  }
-
-  void WillInvokeOnClientOverview(size_t scheduled_size) {
-    ON_CALL(*mock_schedule_service(), GetClientOverview(_, _))
-        .WillByDefault(
-            Invoke([scheduled_size](
-                       SchedulerClientType type,
-                       notifications::ClientOverview::ClientOverviewCallback
-                           callback) {
-              ClientOverview overview;
-              overview.num_scheduled_notifications = scheduled_size;
-              std::move(callback).Run(overview);
-            }));
-  }
-
-  void AddReadingList() {
-    reading_list_model()->AddOrReplaceEntry(
-        GURL("https://a.example.com"), "title",
-        reading_list::ADDED_VIA_CURRENT_APP,
-        /*estimated_read_time=*/base::TimeDelta());
-  }
-
- private:
-  base::SimpleTestClock clock_;
-  base::test::TaskEnvironment task_environment_;
-  std::unique_ptr<ReadingListModelImpl> reading_list_model_;
-  raw_ptr<MockDelegate> delegate_;
-  MockNotificationScheduleService mock_schedule_service_;
-  std::unique_ptr<ReadingListNotificationServiceImpl> service_;
-};
-
-TEST_F(ReadingListNotificationServiceTest, OnClick) {
-  EXPECT_CALL(*delegate(), OpenReadingListPage());
-  service()->OnClick();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest, OnStartWithoutUnreadPages) {
-  EXPECT_EQ(0u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType));
-  service()->OnStart();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest, OnStartWithNotificationScheduled) {
-  AddReadingList();
-  EXPECT_EQ(1u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType))
-      .Times(0);
-  EXPECT_CALL(*mock_schedule_service(), Schedule(_)).Times(0);
-  WillInvokeOnClientOverview(/*scheduled_size=*/1u);
-  service()->OnStart();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest,
-       OnStartWithoutNotificationScheduled) {
-  AddReadingList();
-  EXPECT_EQ(1u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType))
-      .Times(0);
-  EXPECT_CALL(*mock_schedule_service(),
-              Schedule(DeliverOnTime(MakeLocalTime(kShowTime))));
-  WillInvokeOnClientOverview(/*scheduled_size=*/0u);
-  service()->OnStart();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest, BeforeShowWithoutUnreadPages) {
-  EXPECT_EQ(0u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType));
-  EXPECT_CALL(*mock_schedule_service(), Schedule(_)).Times(0);
-  WillInvokeOnClientOverview(/*scheduled_size=*/1u);
-  base::RunLoop loop;
-  auto notif_data = std::make_unique<notifications::NotificationData>();
-  auto callback = base::BindLambdaForTesting(
-      [&](std::unique_ptr<notifications::NotificationData> data) {
-        EXPECT_EQ(nullptr, data) << "The notification should be canceled.";
-        loop.Quit();
-      });
-  service()->BeforeShowNotification(std::move(notif_data), std::move(callback));
-  loop.Run();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest,
-       BeforeShowWithUnreadPageWithoutScheduled) {
-  AddReadingList();
-  EXPECT_EQ(1u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType))
-      .Times(0);
-  EXPECT_CALL(*mock_schedule_service(), Schedule(_));
-  WillInvokeOnClientOverview(/*scheduled_size=*/0u);
-  base::RunLoop loop;
-  auto notif_data = std::make_unique<notifications::NotificationData>();
-  auto callback = base::BindLambdaForTesting(
-      [&](std::unique_ptr<notifications::NotificationData> data) {
-        EXPECT_NE(nullptr, data) << "The notification should not be canceled.";
-        loop.Quit();
-      });
-  service()->BeforeShowNotification(std::move(notif_data), std::move(callback));
-  loop.Run();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest,
-       BeforeShowWithUnreadPageWithScheduled) {
-  AddReadingList();
-  EXPECT_EQ(1u, reading_list_model()->unread_size());
-  EXPECT_CALL(*mock_schedule_service(), DeleteNotifications(kNotificationType))
-      .Times(0);
-  EXPECT_CALL(*mock_schedule_service(), Schedule(_)).Times(0);
-  WillInvokeOnClientOverview(/*scheduled_size=*/1u);
-  base::RunLoop loop;
-  auto notif_data = std::make_unique<notifications::NotificationData>();
-  auto callback = base::BindLambdaForTesting(
-      [&](std::unique_ptr<notifications::NotificationData> data) {
-        EXPECT_NE(nullptr, data) << "The notification should not be canceled.";
-        loop.Quit();
-      });
-  service()->BeforeShowNotification(std::move(notif_data), std::move(callback));
-  loop.Run();
-  task_environment()->RunUntilIdle();
-}
-
-TEST_F(ReadingListNotificationServiceTest, CacheClosure) {
-  auto* cached_closure = service()->GetCachedClosureForTesting();
-  base::RunLoop loop;
-  auto closure = base::BindLambdaForTesting([&]() { loop.Quit(); });
-  cached_closure->emplace(std::move(closure));
-
-  // Flush the cached closures.
-  service()->ReadingListModelLoaded(reading_list_model());
-  loop.Run();
-}
-
-TEST_F(ReadingListNotificationServiceTest, IsEnabled) {
-  {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitWithFeatures({}, {kReadLaterReminderNotification});
-    EXPECT_FALSE(ReadingListNotificationService::IsEnabled());
-  }
-  {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitWithFeatures({kReadLaterReminderNotification}, {});
-    EXPECT_TRUE(ReadingListNotificationService::IsEnabled());
-  }
-}
-
-}  // namespace
diff --git a/chrome/browser/resources/app_home/app_item.html b/chrome/browser/resources/app_home/app_item.html
index 358b221..8e52da88 100644
--- a/chrome/browser/resources/app_home/app_item.html
+++ b/chrome/browser/resources/app_home/app_item.html
@@ -1,4 +1,4 @@
-<style>
+<style include="cr-hidden-style">
 /* TODO(crbug.com/1350406): update the style after UI design
   spec is finalized.*/
 
diff --git a/chrome/browser/resources/app_home/app_item.ts b/chrome/browser/resources/app_home/app_item.ts
index 63a1f02..fffbee24 100644
--- a/chrome/browser/resources/app_home/app_item.ts
+++ b/chrome/browser/resources/app_home/app_item.ts
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import '//resources/cr_elements/cr_hidden_style.css.js';
 import '//resources/cr_elements/cr_checkbox/cr_checkbox.js';
 
 import {CrActionMenuElement} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js';
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html
index 2aee335b..5ca6bab 100644
--- a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.html
@@ -111,12 +111,12 @@
           visit="[[cluster.visits.0]]" on-click="onVisitTileClick_"
           on-aux-click="onVisitTileClick_">
       </ntp-history-clusters-tile>
-      <template is="dom-if" if="[[shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[shouldShowCartTile_(cart)]]" restamp>
         <ntp-history-clusters-cart-tile
             id="cartTile" cart="[[cart]]">
         </ntp-history-clusters-cart-tile>
       </template>
-      <template is="dom-if" if="[[!shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[!shouldShowCartTile_(cart)]]" restamp>
         <ntp-history-clusters-tile class="secondary-tile" medium-format
             visit="[[cluster.visits.1]]" on-click="onVisitTileClick_"
             on-aux-click="onVisitTileClick_">
@@ -134,12 +134,12 @@
           visit="[[cluster.visits.0]]" on-click="onVisitTileClick_"
           on-aux-click="onVisitTileClick_">
       </ntp-history-clusters-tile>
-      <template is="dom-if" if="[[shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[shouldShowCartTile_(cart)]]" restamp>
         <ntp-history-clusters-cart-tile
             id="cartTile" cart="[[cart]]">
         </ntp-history-clusters-cart-tile>
       </template>
-      <template is="dom-if" if="[[!shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[!shouldShowCartTile_(cart)]]" restamp>
         <div class="small-tiles">
           <ntp-history-clusters-tile small-format visit="[[cluster.visits.1]]"
               on-click="onVisitTileClick_" on-aux-click="onVisitTileClick_">
@@ -165,12 +165,12 @@
             on-click="onVisitTileClick_" on-aux-click="onVisitTileClick_">
         </ntp-history-clusters-tile>
       </div>
-      <template is="dom-if" if="[[shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[shouldShowCartTile_(cart)]]" restamp>
         <ntp-history-clusters-cart-tile
             id="cartTile" cart="[[cart]]">
         </ntp-history-clusters-cart-tile>
       </template>
-      <template is="dom-if" if="[[!shouldShowCartTile_()]]" restamp>
+      <template is="dom-if" if="[[!shouldShowCartTile_(cart)]]" restamp>
         <div class="small-tiles">
           <ntp-history-clusters-tile small-format visit="[[cluster.visits.2]]"
               on-click="onVisitTileClick_" on-aux-click="onVisitTileClick_">
diff --git a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.ts b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.ts
index fe43aef..483894b 100644
--- a/chrome/browser/resources/new_tab_page/modules/history_clusters/module.ts
+++ b/chrome/browser/resources/new_tab_page/modules/history_clusters/module.ts
@@ -13,6 +13,7 @@
 import {Cart} from '../../cart.mojom-webui.js';
 import {Cluster, URLVisit} from '../../history_cluster_types.mojom-webui.js';
 import {I18nMixin, loadTimeData} from '../../i18n_setup.js';
+import {NewTabPageProxy} from '../../new_tab_page_proxy.js';
 import {InfoDialogElement} from '../info_dialog';
 import {ModuleDescriptor} from '../module_descriptor.js';
 
@@ -86,7 +87,10 @@
       cluster: Object,
 
       /** The cart displayed by this element, could be null. */
-      cart: Object,
+      cart: {
+        type: Object,
+        value: null,
+      },
 
       searchResultPage: Object,
     };
@@ -96,6 +100,7 @@
   cart: Cart|null;
   layoutType: HistoryClusterLayoutType;
   searchResultPage: URLVisit;
+  private setDisabledModulesListenerId_: number|null = null;
 
   override ready() {
     super.ready();
@@ -116,6 +121,36 @@
     });
   }
 
+  override connectedCallback() {
+    super.connectedCallback();
+
+    if (loadTimeData.getBoolean(
+            'modulesChromeCartInHistoryClustersModuleEnabled')) {
+      this.setDisabledModulesListenerId_ =
+          NewTabPageProxy.getInstance()
+              .callbackRouter.setDisabledModules.addListener(
+                  async (_: boolean, ids: string[]) => {
+                    if (ids.includes('chrome_cart')) {
+                      this.cart = null;
+                    } else if (!this.cart) {
+                      const {cart} =
+                          await HistoryClustersProxyImpl.getInstance()
+                              .handler.getCartForCluster(this.cluster);
+                      this.cart = cart;
+                    }
+                  });
+    }
+  }
+
+  override disconnectedCallback() {
+    super.disconnectedCallback();
+
+    if (this.setDisabledModulesListenerId_) {
+      NewTabPageProxy.getInstance().callbackRouter.removeListener(
+          this.setDisabledModulesListenerId_);
+    }
+  }
+
   private isLayout_(type: HistoryClusterLayoutType): boolean {
     return type === this.layoutType;
   }
@@ -195,10 +230,10 @@
     HistoryClustersProxyImpl.getInstance().handler.openUrlsInTabGroup(urls);
   }
 
-  private shouldShowCartTile_(): boolean {
+  private shouldShowCartTile_(cart: Object): boolean {
     return loadTimeData.getBoolean(
                'modulesChromeCartInHistoryClustersModuleEnabled') &&
-        !!this.cart;
+        !!cart;
   }
 }
 
diff --git a/chrome/browser/resources/settings/chromeos/css/base.css b/chrome/browser/resources/settings/chromeos/css/base.css
index bc462be..cc723d29 100644
--- a/chrome/browser/resources/settings/chromeos/css/base.css
+++ b/chrome/browser/resources/settings/chromeos/css/base.css
@@ -35,3 +35,8 @@
   height: 100%;
   margin: 0;
 }
+
+body {
+  /* Override default font from text_defaults_md.css. */
+  font: var(--cros-body-2-font);
+}
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.ts b/chrome/browser/resources/settings/chromeos/lazy_load.ts
index ae53acc..fbffab75 100644
--- a/chrome/browser/resources/settings/chromeos/lazy_load.ts
+++ b/chrome/browser/resources/settings/chromeos/lazy_load.ts
@@ -115,6 +115,8 @@
 export {TetherConnectionDialogElement} from './internet_page/tether_connection_dialog.js';
 export {KeyboardShortcutBanner} from './keyboard_shortcut_banner/keyboard_shortcut_banner.js';
 export {SettingsMultideviceCombinedSetupItemElement} from './multidevice_page/multidevice_combined_setup_item.js';
+export {SettingsMultideviceFeatureItemElement} from './multidevice_page/multidevice_feature_item.js';
+export {SettingsMultideviceFeatureToggleElement} from './multidevice_page/multidevice_feature_toggle.js';
 export {SettingsMultideviceSmartlockItemElement} from './multidevice_page/multidevice_smartlock_item.js';
 export {SettingsMultideviceTaskContinuationDisabledLinkElement} from './multidevice_page/multidevice_task_continuation_disabled_link.js';
 export {SettingsMultideviceTaskContinuationItemElement} from './multidevice_page/multidevice_task_continuation_item.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_page_visibility.ts b/chrome/browser/resources/settings/chromeos/os_page_availability.ts
similarity index 81%
rename from chrome/browser/resources/settings/chromeos/os_page_visibility.ts
rename to chrome/browser/resources/settings/chromeos/os_page_availability.ts
index 1de0b01..bf1434c 100644
--- a/chrome/browser/resources/settings/chromeos/os_page_visibility.ts
+++ b/chrome/browser/resources/settings/chromeos/os_page_availability.ts
@@ -2,12 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+/**
+ * @fileoverview
+ * This is the single source of truth for top-level page availability in
+ * ChromeOS Settings. An available page is one reachable to the user via some
+ * UI action. A page can be (un)available based on guest mode and/or enabled
+ * features.
+ *
+ * NOTE: This is separate from page visibility, which deals with what pages are
+ * visible to the user. For example, after removing infinite scroll b/272139876
+ * the bluetooth page can be available/accessible, but might not be the active
+ * visible page.
+ */
+
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 
-/**
- * Specifies page visibility based on incognito status and ChromeOS guest mode.
- */
-export interface OsPageVisibility {
+export interface OsPageAvailability {
   a11y: boolean;
   advancedSettings: boolean;
   appearance: {
@@ -49,19 +59,16 @@
   reset: boolean;
 }
 
+const isGuestMode = loadTimeData.getBoolean('isGuest');
 const isAccountManagerEnabled =
     loadTimeData.valueExists('isAccountManagerEnabled') &&
     loadTimeData.getBoolean('isAccountManagerEnabled');
 const isKerberosEnabled = loadTimeData.valueExists('isKerberosEnabled') &&
     loadTimeData.getBoolean('isKerberosEnabled');
-const isGuestMode = loadTimeData.getBoolean('isGuest');
 
-/**
- * Dictionary defining page visibility.
- */
-let osPageVisibility: OsPageVisibility;
+let osPageAvailability: OsPageAvailability;
 if (isGuestMode) {
-  osPageVisibility = {
+  osPageAvailability = {
     a11y: true,
     advancedSettings: true,
     appearance: {
@@ -99,7 +106,7 @@
     reset: false,
   };
 } else {
-  osPageVisibility = {
+  osPageAvailability = {
     a11y: true,
     advancedSettings: true,
     appearance: {
@@ -142,4 +149,4 @@
   };
 }
 
-export {osPageVisibility};
+export {osPageAvailability};
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
index fbc9a54..2b6d2ea 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.html
@@ -92,7 +92,7 @@
         learn-more-url="$i18n{syncAndGoogleServicesLearnMoreURL}">
       <os-settings-sync-subpage
           sync-status="[[syncStatus]]" prefs="{{prefs}}"
-          page-visibility="[[pageVisibility.privacy]]"
+          page-availability="[[pageAvailability.privacy]]"
           focus-config="[[focusConfig_]]">
       </os-settings-sync-subpage>
     </os-settings-subpage>
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.ts b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.ts
index a90b0ad..96c5161 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.ts
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_people_page.ts
@@ -29,7 +29,7 @@
 import {DeepLinkingMixin} from '../deep_linking_mixin.js';
 import {LockStateMixin} from '../lock_state_mixin.js';
 import {Setting} from '../mojom-webui/setting.mojom-webui.js';
-import {OsPageVisibility} from '../os_page_visibility.js';
+import {OsPageAvailability} from '../os_page_availability.js';
 import {routes} from '../os_settings_routes.js';
 import {RouteObserverMixin} from '../route_observer_mixin.js';
 import {Route, Router} from '../router.js';
@@ -62,9 +62,9 @@
       syncStatus: Object,
 
       /**
-       * Dictionary defining page visibility.
+       * Dictionary defining page availability.
        */
-      pageVisibility: Object,
+      pageAvailability: Object,
 
       authToken_: {
         type: Object,
@@ -172,7 +172,7 @@
   }
 
   syncStatus: SyncStatus;
-  pageVisibility: OsPageVisibility;
+  pageAvailability: OsPageAvailability;
   private authToken_: chrome.quickUnlockPrivate.TokenInfo|undefined;
   private profileIconUrl_: string;
   private profileName_: string;
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts
index bf1df4d2..32500cc 100644
--- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts
+++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_subpage.ts
@@ -99,9 +99,9 @@
       },
 
       /**
-       * Dictionary defining page visibility.
+       * Dictionary defining page availability.
        */
-      pageVisibility: Object,
+      pageAvailability: Object,
 
       /**
        * The current sync preferences, supplied by SyncBrowserProxy.
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.html b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.html
index 3f9cb55..d41adf8 100644
--- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.html
+++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.html
@@ -25,8 +25,8 @@
             icon="cr20:domain">
           </iron-icon>
           <iron-icon id="printerStatusIcon"
-            hidden="[[!showPrinterStatusIcon_(printerEntry.printerType)]]"
-            icon="[[getPrinterStatusIcon_(
+            hidden="[[!showPrinterIcon_(printerEntry.printerType)]]"
+            icon="[[getPrinterIcon_(printerEntry.printerType,
                 printerEntry.printerInfo.printerStatusReason)]]">
           </iron-icon>
           [[printerEntry.printerInfo.printerName]]
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts
index d7889c5..fc9b73db 100644
--- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts
+++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts
@@ -69,6 +69,17 @@
         },
         readOnly: true,
       },
+
+      /**
+       * True when the "printer-settings-revamp" feature flag is enabled.
+       */
+      isPrinterSettingsRevampEnabled_: {
+        type: Boolean,
+        value: () => {
+          return loadTimeData.getBoolean('isPrinterSettingsRevampEnabled');
+        },
+        readOnly: true,
+      },
     };
   }
 
@@ -145,6 +156,10 @@
     return this.printerEntry.printerType === PrinterType.SAVED;
   }
 
+  private isEnterprisePrinter_(): boolean {
+    return this.printerEntry.printerType === PrinterType.ENTERPRISE;
+  }
+
   private isConfigureDisabled_(): boolean {
     return !this.userPrintersAllowed || this.savingPrinter;
   }
@@ -159,12 +174,31 @@
         'setupPrinterAria', this.printerEntry.printerInfo.printerName);
   }
 
+  // The standard printer icon shows for printer entries classified as nearby
+  // printers. An exception is enterprise printers which display the managed
+  // icon.
+  private showNearbyPrinterIcon_(): boolean {
+    return !this.isSavedPrinter_() && !this.isEnterprisePrinter_() &&
+        this.isPrinterSettingsRevampEnabled_;
+  }
+
+  // Printer status icons are only shown for saved printers.
   private showPrinterStatusIcon_(): boolean {
     return this.isSavedPrinter_() &&
         this.isPrinterSettingsPrinterStatusEnabled_;
   }
 
-  private getPrinterStatusIcon_(): string {
+  private showPrinterIcon_(): boolean {
+    return this.showNearbyPrinterIcon_() || this.showPrinterStatusIcon_();
+  }
+
+  private getPrinterIcon_(): string {
+    // Only saved printers need to display an icon with printer status.
+    if (!this.isSavedPrinter_()) {
+      // TODO(b/278621575): Replace with standard printer icon once available.
+      return `os-settings:printer-status-green`;
+    }
+
     let iconColor = '';
     switch (computePrinterState(
         this.printerEntry.printerInfo.printerStatusReason)) {
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts
index 816b817e..f87e32c 100644
--- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts
+++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts
@@ -17,6 +17,8 @@
 import './cups_printers_entry.js';
 
 import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {recordSettingChange} from '../metrics_recorder.js';
@@ -26,6 +28,7 @@
 import {CupsPrinterInfo, CupsPrintersBrowserProxy, CupsPrintersBrowserProxyImpl} from './cups_printers_browser_proxy.js';
 import {CupsPrintersEntryListMixin} from './cups_printers_entry_list_mixin.js';
 import {getTemplate} from './cups_saved_printers.html.js';
+import {getStatusReasonFromPrinterStatus, PrinterStatus} from './printer_status.js';
 
 /**
  * If the Show more button is visible, the minimum number of printers we show
@@ -118,6 +121,19 @@
        * Used by FocusRowBehavior to track if the list has been blurred.
        */
       listBlurred_: Boolean,
+
+      /**
+       * True when the "printer-settings-printer-status" feature flag is
+       * enabled.
+       */
+      isPrinterSettingsPrinterStatusEnabled_: {
+        type: Boolean,
+        value: () => {
+          return loadTimeData.getBoolean(
+              'isPrinterSettingsPrinterStatusEnabled');
+        },
+        readOnly: true,
+      },
     };
   }
 
@@ -125,6 +141,7 @@
     return [
       'onSearchOrPrintersChanged_(savedPrinters.*, searchTerm,' +
           'hasShowMoreBeenTapped_, newPrinters_.*)',
+      'fetchPrinterStatuses_(savedPrinters.splices)',
     ];
   }
 
@@ -140,6 +157,7 @@
   private listBlurred_: boolean;
   private newPrinters_: PrinterListEntry[];
   private visiblePrinterCounter_: number;
+  private isPrinterSettingsPrinterStatusEnabled_: boolean;
 
   constructor() {
     super();
@@ -334,6 +352,53 @@
   private getFilteredPrintersLength_(): number {
     return this.filteredPrinters_.length;
   }
+
+  /** Query each saved printer for its printer status. */
+  private fetchPrinterStatuses_() {
+    if (!this.isPrinterSettingsPrinterStatusEnabled_) {
+      return;
+    }
+
+    this.savedPrinters.forEach(printer => {
+      this.browserProxy_
+          .requestPrinterStatusUpdate(printer.printerInfo.printerId)
+          .then(printerStatus => this.onPrinterStatusReceived_(printerStatus));
+    });
+  }
+
+  /**
+   * For each printer status received, search for its respective saved printer
+   * and update its status.
+   */
+  private onPrinterStatusReceived_(printerStatus: PrinterStatus) {
+    assert(this.isPrinterSettingsPrinterStatusEnabled_);
+    if (!printerStatus) {
+      return;
+    }
+
+    // Find the associated printer and set its status reason.
+    const index = this.savedPrinters.findIndex(
+        printer => printer.printerInfo.printerId === printerStatus.printerId);
+    if (index === -1) {
+      return;
+    }
+
+    this.savedPrinters[index].printerInfo.printerStatusReason =
+        getStatusReasonFromPrinterStatus(printerStatus);
+
+
+    // Even though the online state is set on `savedPrinters`, the actual
+    // printer entries displayed are from `filteredPrinters_`. So notify the
+    // specific filtered printer entry to update its icon.
+    const filteredIndex = this.filteredPrinters_.findIndex(
+        printer => printer.printerInfo.printerId === printerStatus.printerId);
+    if (filteredIndex === -1) {
+      return;
+    }
+
+    this.notifyPath(
+        `filteredPrinters_.${filteredIndex}.printerInfo.printerStatusReason`);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index d2f3547..fab5225 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -374,7 +374,7 @@
   "chromeos/os_languages_page/languages_browser_proxy.ts",
   "chromeos/os_languages_page/languages_metrics_proxy.ts",
   "chromeos/os_languages_page/languages_types.ts",
-  "chromeos/os_page_visibility.ts",
+  "chromeos/os_page_availability.ts",
   "chromeos/os_people_page/account_manager_browser_proxy.ts",
   "chromeos/os_people_page/fingerprint_browser_proxy.ts",
   "chromeos/os_people_page/os_sync_browser_proxy.ts",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.ts b/chrome/browser/resources/settings/chromeos/os_settings.ts
index ab15702..4bb37dd 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.ts
+++ b/chrome/browser/resources/settings/chromeos/os_settings.ts
@@ -104,6 +104,7 @@
 export {ProfileInfoBrowserProxyImpl} from '/shared/settings/people_page/profile_info_browser_proxy.js';
 export {PageStatus, StatusAction, StoredAccount, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from '/shared/settings/people_page/sync_browser_proxy.js';
 export {PrivacyPageBrowserProxyImpl, SecureDnsMode, SecureDnsUiManagementMode} from '/shared/settings/privacy_page/privacy_page_browser_proxy.js';
+export {LocalizedLinkElement} from 'chrome://resources/cr_components/localized_link/localized_link.js';
 export {SettingsPrefsElement} from 'chrome://resources/cr_components/settings_prefs/prefs.js';
 export {CrSettingsPrefs} from 'chrome://resources/cr_components/settings_prefs/prefs_types.js';
 export {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
@@ -173,7 +174,7 @@
 export {FastPairSavedDevice, FastPairSavedDevicesOptInStatus} from './os_bluetooth_page/settings_fast_pair_constants.js';
 export {GoogleDriveBrowserProxy, GoogleDrivePageCallbackRouter, GoogleDrivePageHandlerRemote, GoogleDrivePageRemote, Stage} from './os_files_page/google_drive_browser_proxy.js';
 export {ConfirmationDialogType, SettingsGoogleDriveSubpageElement} from './os_files_page/google_drive_subpage.js';
-export {osPageVisibility} from './os_page_visibility.js';
+export {osPageAvailability} from './os_page_availability.js';
 export {MetricsConsentBrowserProxy, MetricsConsentBrowserProxyImpl, MetricsConsentState} from './os_privacy_page/metrics_consent_browser_proxy.js';
 export {OsSettingsPrivacyPageElement} from './os_privacy_page/os_privacy_page.js';
 export {DataAccessPolicyState, PeripheralDataAccessBrowserProxy, PeripheralDataAccessBrowserProxyImpl} from './os_privacy_page/peripheral_data_access_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.html b/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.html
index a0544be..1e44e56 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.html
+++ b/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.html
@@ -40,7 +40,7 @@
   <os-settings-page
       class="cr-centered-card-container"
       prefs="{{prefs}}"
-      page-visibility="[[pageVisibility]]"
+      page-availability="[[pageAvailability]]"
       show-android-apps="[[showAndroidApps]]"
       show-arcvm-manage-usb="[[showArcvmManageUsb]]";
       show-crostini="[[showCrostini]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.ts b/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.ts
index dddd3ad..8968d02 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.ts
+++ b/chrome/browser/resources/settings/chromeos/os_settings_main/os_settings_main.ts
@@ -21,7 +21,7 @@
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {assertExists} from '../assert_extras.js';
-import {OsPageVisibility} from '../os_page_visibility.js';
+import {OsPageAvailability} from '../os_page_availability.js';
 import {routes} from '../os_settings_routes.js';
 import {RouteObserverMixin} from '../route_observer_mixin.js';
 import {Route, Router} from '../router.js';
@@ -90,9 +90,9 @@
       },
 
       /**
-       * Dictionary defining page visibility.
+       * Dictionary defining page availability.
        */
-      pageVisibility: Object,
+      pageAvailability: Object,
 
       showAndroidApps: Boolean,
 
@@ -113,7 +113,7 @@
   prefs: Object;
   advancedToggleExpanded: boolean;
   toolbarSpinnerActive: boolean;
-  pageVisibility: OsPageVisibility;
+  pageAvailability: OsPageAvailability;
   showAndroidApps: boolean;
   showArcvmManageUsb: boolean;
   showCrostini: boolean;
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
index c499b644..21b8dff 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
@@ -151,7 +151,7 @@
       <os-settings-section page-title="$i18n{osPeoplePageTitle}"
           section="osPeople">
         <os-settings-people-page prefs="{{prefs}}"
-            page-visibility="[[pageVisibility]]">
+            page-availability="[[pageAvailability]]">
         </os-settings-people-page>
       </os-settings-section>
     </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
index 73e34c1..0805aab 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
+++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.ts
@@ -39,7 +39,7 @@
 import {MainPageMixin} from '../main_page_mixin.js';
 import {AboutPageBrowserProxyImpl} from '../os_about_page/about_page_browser_proxy.js';
 import {AndroidAppsBrowserProxyImpl, AndroidAppsInfo} from '../os_apps_page/android_apps_browser_proxy.js';
-import {OsPageVisibility} from '../os_page_visibility.js';
+import {OsPageAvailability} from '../os_page_availability.js';
 import {routes} from '../os_settings_routes.js';
 import {Route, Router} from '../router.js';
 
@@ -96,9 +96,9 @@
       },
 
       /**
-       * Dictionary defining page visibility.
+       * Dictionary defining page availability.
        */
-      pageVisibility: {
+      pageAvailability: {
         type: Object,
         value() {
           return {};
@@ -155,7 +155,7 @@
   }
 
   androidAppsInfo?: AndroidAppsInfo;
-  pageVisibility: OsPageVisibility;
+  pageAvailability: OsPageAvailability;
   advancedToggleExpanded: boolean;
   showKerberosSection: boolean;
   private allowCrostini_: boolean;
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html
index 6d5f9cc..8f4685e 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html
+++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html
@@ -132,6 +132,7 @@
   <div id="left">
     <template is="dom-if" if="[[showNavMenu_]]">
       <os-settings-menu
+          page-availability="[[pageAvailability_]]"
           on-iron-activate="onSectionSelect_"
           advanced-opened="{{advancedOpenedInMenu_}}"
           show-kerberos-section="[[showKerberosSection_]]"
@@ -139,9 +140,10 @@
       </os-settings-menu>
     </template>
   </div>
-  <os-settings-main id="main" prefs="{{prefs}}"
+  <os-settings-main id="main"
+      prefs="{{prefs}}"
       toolbar-spinner-active="{{toolbarSpinnerActive_}}"
-      page-visibility="[[pageVisibility_]]"
+      page-availability="[[pageAvailability_]]"
       show-android-apps="[[showAndroidApps_]]"
       show-arcvm-manage-usb="[[showArcvmManageUsb_]]"
       show-crostini="[[showCrostini_]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts
index 79ad631..91bfe68 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts
+++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts
@@ -36,7 +36,7 @@
 import {setGlobalScrollTarget} from '../common/global_scroll_target_mixin.js';
 import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSettingChange} from '../metrics_recorder.js';
 import {convertPrefToSettingMetric} from '../metrics_utils.js';
-import {OsPageVisibility, osPageVisibility} from '../os_page_visibility.js';
+import {OsPageAvailability, osPageAvailability} from '../os_page_availability.js';
 import {OsToolbarElement} from '../os_toolbar/os_toolbar.js';
 import {RouteObserverMixin} from '../route_observer_mixin.js';
 import {Route, Router} from '../router.js';
@@ -128,7 +128,15 @@
         observer: 'onNarrowChanged_',
       },
 
-      pageVisibility_: {type: Object, value: osPageVisibility},
+      /**
+       * Used to determine which pages and menu items are available (not to be
+       * confused with page visibility) to the user.
+       * See os_page_availability.ts for more details.
+       */
+      pageAvailability_: {
+        type: Object,
+        value: osPageAvailability,
+      },
 
       havePlayStoreApp_: Boolean,
 
@@ -166,7 +174,7 @@
   private advancedOpenedInMain_: boolean;
   private advancedOpenedInMenu_: boolean;
   private toolbarSpinnerActive_: boolean;
-  private pageVisibility_: OsPageVisibility;
+  private pageAvailability_: OsPageAvailability;
   private havePlayStoreApp_: boolean;
   private showAndroidApps_: boolean;
   private showArcvmManageUsb_: boolean;
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc
index c2820062..53d062b7 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc
@@ -305,7 +305,9 @@
   active_tokens_[raw_request] = token;
 
   if ((!binary_fcm_service_ || !binary_fcm_service_->Connected()) &&
-      !is_auth_request) {
+      !is_auth_request &&
+      raw_request->analysis_connector() !=
+          enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY) {
     base::TimeDelta first_backoff;
     if (*IgnoreFCMDelaysStorage()) {
       first_backoff = base::Seconds(0);
@@ -329,9 +331,11 @@
   }
 
   bool is_auth_request = request->IsAuthRequest();
-  // Auth requests are never going to need waiting for an async response, so
-  // don't bother getting a token from `binary_fcm_service_`.
-  if (is_auth_request) {
+  // Auth requests and paste requests are never going to need waiting for an
+  // async response, so don't bother getting a token from `binary_fcm_service_`.
+  if (is_auth_request ||
+      request->analysis_connector() ==
+          enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY) {
     request->GetRequestData(
         base::BindOnce(&CloudBinaryUploadService::OnGetRequestData,
                        weakptr_factory_.GetWeakPtr(), request));
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc
index 05d43fc..3b08f01 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc
@@ -361,6 +361,25 @@
   EXPECT_EQ(scanning_result, BinaryUploadService::Result::FAILED_TO_GET_TOKEN);
 }
 
+TEST_F(CloudBinaryUploadServiceTest, PasteSucceedsWhenMissingInstanceID) {
+  BinaryUploadService::Result scanning_result;
+  enterprise_connectors::ContentAnalysisResponse scanning_response;
+
+  std::unique_ptr<MockRequest> request =
+      MakeRequest(&scanning_result, &scanning_response, /*is_app*/ false);
+  request->set_analysis_connector(
+      enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY);
+
+  // Paste requests never requests an instance ID, so they should get normal
+  // responses despite the FCM service being mocked to return an invalid one.
+  ExpectInstanceID(BinaryFCMService::kInvalidId, 0);
+
+  UploadForDeepScanning(std::move(request));
+  content::RunAllTasksUntilIdle();
+
+  EXPECT_EQ(scanning_result, BinaryUploadService::Result::SUCCESS);
+}
+
 TEST_F(CloudBinaryUploadServiceTest, FailsWhenUploadFails) {
   BinaryUploadService::Result scanning_result;
   enterprise_connectors::ContentAnalysisResponse scanning_response;
diff --git a/chrome/browser/site_isolation/chrome_site_isolation_policy_unittest.cc b/chrome/browser/site_isolation/chrome_site_isolation_policy_unittest.cc
index 85e4ff3..5e97427 100644
--- a/chrome/browser/site_isolation/chrome_site_isolation_policy_unittest.cc
+++ b/chrome/browser/site_isolation/chrome_site_isolation_policy_unittest.cc
@@ -12,6 +12,7 @@
 #include "chrome/common/chrome_features.h"
 #include "components/site_isolation/features.h"
 #include "components/site_isolation/preloaded_isolated_origins.h"
+#include "components/site_isolation/site_isolation_policy.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/site_isolation_policy.h"
 #include "content/public/common/content_features.h"
@@ -62,6 +63,13 @@
     EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
 
     mode_feature_.InitAndEnableFeature(features::kSitePerProcess);
+    site_isolation::SiteIsolationPolicy::
+        SetDisallowMemoryThresholdCachingForTesting(true);
+  }
+
+  void TearDown() override {
+    site_isolation::SiteIsolationPolicy::
+        SetDisallowMemoryThresholdCachingForTesting(false);
   }
 
   // Note that this only sets the memory threshold for strict site isolation,
@@ -89,8 +97,7 @@
       content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites());
 }
 
-// Disabled since it's flaky. https://crbug.com/1406992
-TEST_F(ChromeSiteIsolationPolicyTest, DISABLED_IsolationAboveMemoryThreshold) {
+TEST_F(ChromeSiteIsolationPolicyTest, IsolationAboveMemoryThreshold) {
   if (ShouldSkipBecauseOfConflictingCommandLineSwitches())
     return;
 
@@ -98,9 +105,7 @@
   EXPECT_TRUE(content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites());
 }
 
-// Disabled since it's flaky. https://crbug.com/1406992
-TEST_F(ChromeSiteIsolationPolicyTest,
-       DISABLED_IsolatedOriginsContainChromeOrigins) {
+TEST_F(ChromeSiteIsolationPolicyTest, IsolatedOriginsContainChromeOrigins) {
   if (ShouldSkipBecauseOfConflictingCommandLineSwitches())
     return;
 
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
index dc9e657..7ad6d908 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.h"
-#include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
@@ -349,7 +348,6 @@
 void ChildAccountService::StartFetchingFamilyInfo() {
   list_family_members_fetcher_ = FetchListFamilyMembers(
       *identity_manager_, profile_->GetURLLoaderFactory(),
-      KidsManagementService::GetEndpointUrl(),
       base::BindOnce(&ChildAccountService::OnResponse, base::Unretained(this)));
 }
 
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
index fbc0ba43..c1ccf5b5 100644
--- a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
+++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
@@ -237,7 +237,7 @@
 
 void KidsManagementService::StartFetchFamilyMembers() {
   list_family_members_fetcher_ = FetchListFamilyMembers(
-      *identity_manager_, url_loader_factory_, GetEndpointUrl(),
+      *identity_manager_, url_loader_factory_,
       BindOnce(&KidsManagementService::ConsumeListFamilyMembers,
                Unretained(this)));
 }
@@ -287,12 +287,6 @@
   return list_family_members_timer_.IsRunning();
 }
 
-const std::string& KidsManagementService::GetEndpointUrl() {
-  static const NoDestructor<std::string> nonce(
-      "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/");
-  return *nonce;
-}
-
 KidsManagementServiceFactory::KidsManagementServiceFactory()
     : ProfileKeyedServiceFactory(
           "KidsManagementService",
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
index 63a34fb..d9243bd8 100644
--- a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
+++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
@@ -80,8 +80,6 @@
     return family_members_;
   }
 
-  static const std::string& GetEndpointUrl();
-
   // Responds whether at least one request for child status was successful.
   // And we got answer whether the profile belongs to a child account or not.
   bool IsChildAccountStatusKnown() const;
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
index 2111810..939f8b7 100644
--- a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
+++ b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
@@ -183,8 +183,10 @@
         base::Contains(supervised_user_interstitials_,
                        render_frame_host->GetFrameTreeNodeId());
     int count = supervised_user_interstitials_.size();
-    if (main_frame_blocked)
+    if (main_frame_blocked) {
       count = 0;
+      supervised_user_service_->MarkFirstTimeInterstitialBannerShown();
+    }
 
     UMA_HISTOGRAM_COUNTS_1000("ManagedUsers.BlockedIframeCount", count);
   }
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index b9482b3..ca25d5f 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -65,6 +65,10 @@
   for (const char* pref : supervised_user::kCustodianInfoPrefs) {
     registry->RegisterStringPref(pref, std::string());
   }
+  registry->RegisterIntegerPref(
+      prefs::kFirstTimeInterstitialBannerState,
+      static_cast<int>(
+          supervised_user::FirstTimeInterstitialBannerState::kUnknown));
 }
 
 void SupervisedUserService::Init() {
@@ -77,7 +81,26 @@
       prefs::kSupervisedUserId,
       base::BindRepeating(&SupervisedUserService::OnSupervisedUserIdChanged,
                           base::Unretained(this)));
+  supervised_user::FirstTimeInterstitialBannerState banner_state =
+      static_cast<supervised_user::FirstTimeInterstitialBannerState>(
+          user_prefs_->GetInteger(prefs::kFirstTimeInterstitialBannerState));
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
+  if (banner_state ==
+          supervised_user::FirstTimeInterstitialBannerState::kUnknown &&
+      !profile_->IsNewProfile()) {
+    banner_state =
+        supervised_user::FirstTimeInterstitialBannerState::kNeedToShow;
+  } else {
+    banner_state =
+        supervised_user::FirstTimeInterstitialBannerState::kSetupComplete;
+  }
+#else
+  banner_state =
+      supervised_user::FirstTimeInterstitialBannerState::kSetupComplete;
+#endif
 
+  user_prefs_->SetInteger(prefs::kFirstTimeInterstitialBannerState,
+                          static_cast<int>(banner_state));
   SetActive(IsSubjectToParentalControls());
 }
 
@@ -404,3 +427,17 @@
   for (SupervisedUserServiceObserver& observer : observer_list_)
     observer.OnURLFilterChanged();
 }
+
+void SupervisedUserService::MarkFirstTimeInterstitialBannerShown() const {
+  supervised_user::FirstTimeInterstitialBannerState banner_state =
+      static_cast<supervised_user::FirstTimeInterstitialBannerState>(
+          user_prefs_->GetInteger(prefs::kFirstTimeInterstitialBannerState));
+
+  if (banner_state ==
+      supervised_user::FirstTimeInterstitialBannerState::kNeedToShow) {
+    user_prefs_->SetInteger(
+        prefs::kFirstTimeInterstitialBannerState,
+        static_cast<int>(
+            supervised_user::FirstTimeInterstitialBannerState::kSetupComplete));
+  }
+}
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index 2ae80d8..01a607d 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -146,6 +146,11 @@
   // is no dedicated method for the feature (e.g IsURLFilteringEnabled).
   bool IsSubjectToParentalControls() const;
 
+  // Updates the kFirstTimeInterstitialBannerState pref to indicate that the
+  // user has been shown the interstitial banner. This will only update users
+  // who haven't yet seen the banner.
+  void MarkFirstTimeInterstitialBannerShown() const;
+
  private:
   friend class SupervisedUserServiceExtensionTestBase;
   friend class SupervisedUserServiceFactory;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 56a6c77..963529c 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3459,6 +3459,7 @@
       "//components/services/app_service/public/cpp:icon_loader",
       "//components/services/app_service/public/cpp:instance_update",
       "//components/session_manager/core",
+      "//components/supervised_user/core/browser:fetcher",
       "//components/tab_groups",
       "//components/user_manager",
       "//content/public/common",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/ActionChipsDelegate.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/ActionChipsDelegate.java
index a450795..afab190 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/ActionChipsDelegate.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/ActionChipsDelegate.java
@@ -8,6 +8,7 @@
 
 /**
  * An interface for handling interactions for Omnibox Action Chips.
+ * TODO(crbug/1418077): repurpose as a OmniboxActionFactory.
  */
 public interface ActionChipsDelegate {
     /**
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index e6b5f7a..4d3d5ed 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3955,14 +3955,6 @@
       <message name="IDS_READING_LIST_MARK_AS_UNREAD" desc="The text for the action to mark the reading list as unread.">
         Mark as unread
       </message>
-      <message name="IDS_READING_LIST_REMINDER_NOTIFICATION_TITLE" desc="The title of the reminder notification for reading list.">
-        Catch up on your reading list
-      </message>
-      <message name="IDS_READING_LIST_REMINDER_NOTIFICATION_SUBTITLE" desc="The subtitle of the reminder notification for reading list.">
-          {READING_LIST_REMINDER_NOTIFICATION_SUBTITLE, plural,
-          =1 {You have <ph name="READING_LIST_REMINDER_NOTIFICATION_SUBTITLE_ONE">%1$d<ex>1</ex></ph> unread page}
-          other {You have <ph name="READING_LIST_REMINDER_NOTIFICATION_SUBTITLE_MANY">%1$d<ex>8</ex></ph> unread pages}}
-      </message>
       <message name="IDS_READING_LIST_UNREAD_PAGE_COUNT" desc="Inform the user about the number of unread reading list items.">
           {READING_LIST_UNREAD_PAGE_COUNT, plural,
           =1 {<ph name="READING_LIST_UNREAD_PAGE_COUNT_ONE">%1$d<ex>1</ex></ph> unread page}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_SUBTITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_SUBTITLE.png.sha1
deleted file mode 100644
index 29500b5..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_SUBTITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6cf21d04da0a910f8aae41e478ee5d347160775e
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_TITLE.png.sha1
deleted file mode 100644
index cee60dd..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_READING_LIST_REMINDER_NOTIFICATION_TITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-cabd9ef05333b9cd70a80d6bcd098f2e3cfc79a3
\ No newline at end of file
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
index 39ff12ce..f7e88ad 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
@@ -592,6 +592,7 @@
     window->SetProperty(chromeos::kEscHoldToExitFullscreen, true);
   } else if (borealis::BorealisWindowManager::IsBorealisWindow(window)) {
     window->SetProperty(chromeos::kUseOverviewToExitFullscreen, true);
+    window->SetProperty(chromeos::kNoExitFullscreenOnLock, true);
     window->SetProperty(chromeos::kUseOverviewToExitPointerLock, true);
   } else if (crostini::IsCrostiniWindow(window)) {
     window->SetProperty(chromeos::kUseOverviewToExitFullscreen, true);
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index 26b98d5..3a36aa1 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -290,10 +290,10 @@
   return current_wallpaper;
 }
 
-scoped_refptr<base::RefCountedMemory>
-TestWallpaperController::GetPreviewImage() {
+void TestWallpaperController::LoadPreviewImage(
+    LoadPreviewImageCallback callback) {
   current_wallpaper.MakeThreadSafe();
-  return gfx::Image(current_wallpaper).As1xPNGBytes();
+  std::move(callback).Run(gfx::Image(current_wallpaper).As1xPNGBytes());
 }
 
 bool TestWallpaperController::IsWallpaperBlurredForLockState() const {
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 13c0678..fdeb243 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -169,7 +169,7 @@
   void AddObserver(ash::WallpaperControllerObserver* observer) override;
   void RemoveObserver(ash::WallpaperControllerObserver* observer) override;
   gfx::ImageSkia GetWallpaperImage() override;
-  scoped_refptr<base::RefCountedMemory> GetPreviewImage() override;
+  void LoadPreviewImage(LoadPreviewImageCallback callback) override;
   bool IsWallpaperBlurredForLockState() const override;
   bool IsActiveUserWallpaperControlledByPolicy() override;
   bool IsWallpaperControlledByPolicy(
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index e52e72d..bc2f7b1 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/check.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/memory/scoped_refptr.h"
@@ -430,10 +431,10 @@
 bool PrintPreviewShowing(const Browser* browser) {
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
   WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
-  printing::PrintPreviewDialogController* controller =
-      printing::PrintPreviewDialogController::GetInstance();
-  return controller && (controller->GetPrintPreviewForContents(contents) ||
-                        controller->is_creating_print_preview_dialog());
+  auto* controller = printing::PrintPreviewDialogController::GetInstance();
+  CHECK(controller);
+  return controller->GetPrintPreviewForContents(contents) ||
+         controller->is_creating_print_preview_dialog();
 #else
   return false;
 #endif
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc
index 4aa93da..19d78647 100644
--- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc
+++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc
@@ -100,9 +100,8 @@
 void ShoppingListUiTabHelper::NavigationEntryCommitted(
     const content::LoadCommittedDetails& load_details) {
   if (!load_details.is_in_active_page ||
-      (web_contents()->GetLastCommittedURL() ==
-           load_details.previous_main_frame_url &&
-       is_initial_navigation_committed_)) {
+      IsInitialNavigationCommitted(load_details) ||
+      IsSameDocumentWithSameCommittedUrl(load_details)) {
     is_initial_navigation_committed_ = true;
     return;
   }
@@ -128,6 +127,20 @@
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
+bool ShoppingListUiTabHelper::IsInitialNavigationCommitted(
+    const content::LoadCommittedDetails& load_details) {
+  return load_details.previous_main_frame_url ==
+             web_contents()->GetLastCommittedURL() &&
+         is_initial_navigation_committed_;
+}
+
+bool ShoppingListUiTabHelper::IsSameDocumentWithSameCommittedUrl(
+    const content::LoadCommittedDetails& load_details) {
+  return load_details.previous_main_frame_url ==
+             web_contents()->GetLastCommittedURL() &&
+         load_details.is_same_document;
+}
+
 void ShoppingListUiTabHelper::DidStopLoading() {
   if (!web_contents()->IsDocumentOnLoadCompletedInPrimaryMainFrame() ||
       !ShouldDelayChipUpdate() || is_first_load_for_nav_finished_) {
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h
index 9beaa22..94330318 100644
--- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h
+++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h
@@ -112,6 +112,12 @@
 
   void TriggerUpdateForIconView();
 
+  bool IsInitialNavigationCommitted(
+      const content::LoadCommittedDetails& load_details);
+
+  bool IsSameDocumentWithSameCommittedUrl(
+      const content::LoadCommittedDetails& load_details);
+
   // The shopping service is tied to the lifetime of the browser context
   // which will always outlive this tab helper.
   raw_ptr<ShoppingService, DanglingUntriaged> shopping_service_;
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 080b5394..f4d78b6 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -302,6 +302,14 @@
   // ChromeSubresourceFilterClient has it as a dependency.
   infobars::ContentInfoBarManager::CreateForWebContents(web_contents);
 
+  // `PageSpecificContentSettings` (PSCS) needs to come before
+  // `DIPSWebContentsObserver` for this latter to be correctly added to the PSCS
+  // observer list.
+  content_settings::PageSpecificContentSettings::CreateForWebContents(
+      web_contents,
+      std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
+          web_contents));
+
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
 
@@ -438,10 +446,6 @@
       web_contents,
       sync_sessions::SyncSessionsWebContentsRouterFactory::GetForProfile(
           profile));
-  content_settings::PageSpecificContentSettings::CreateForWebContents(
-      web_contents,
-      std::make_unique<chrome::PageSpecificContentSettingsDelegate>(
-          web_contents));
   TabUIHelper::CreateForWebContents(web_contents);
   tasks::TaskTabHelper::CreateForWebContents(web_contents);
   ukm::InitializeSourceUrlRecorderForWebContents(web_contents);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
index 552ac82..613be906 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.cc
@@ -4,7 +4,10 @@
 
 #include "chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.h"
 
+#include <unordered_map>
+
 #include "base/token.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.h"
 #include "chrome/browser/ui/tabs/tab_group.h"
@@ -38,6 +41,9 @@
 LocalTabGroupListener::~LocalTabGroupListener() = default;
 
 void LocalTabGroupListener::PauseTracking() {
+  // We can't handle nested multi-step operations. Crash to avoid data loss.
+  CHECK(!paused_);
+
   paused_ = true;
 }
 
@@ -46,7 +52,9 @@
 
   // Thoroughly check for consistency between the data structures we're linking.
   // The saved tabs and the local tabs should match up in the same order.
-  const std::vector<SavedTabGroupTab>& saved_tabs = saved_group()->saved_tabs();
+  const std::vector<SavedTabGroupTab>& saved_tabs =
+      saved_group() ? saved_group()->saved_tabs()
+                    : std::vector<SavedTabGroupTab>();
   const std::vector<content::WebContents*> local_tabs =
       SavedTabGroupUtils::GetWebContentsesInGroup(local_id_);
 
@@ -63,9 +71,10 @@
   }
 }
 
-void LocalTabGroupListener::AddWebContents(content::WebContents* web_contents,
-                                           TabStripModel* tab_strip_model,
-                                           int index) {
+void LocalTabGroupListener::AddWebContentsFromLocal(
+    content::WebContents* web_contents,
+    TabStripModel* tab_strip_model,
+    int index) {
   if (paused_) {
     return;
   }
@@ -96,14 +105,15 @@
                                           model_);
 }
 
-bool LocalTabGroupListener::RemoveWebContentsIfPresent(
+LocalTabGroupListener::Liveness
+LocalTabGroupListener::MaybeRemoveWebContentsFromLocal(
     content::WebContents* web_contents) {
   if (paused_) {
-    return true;
+    return Liveness::kGroupExists;
   }
 
   if (web_contents_to_tab_id_map_.count(web_contents) == 0) {
-    return true;
+    return Liveness::kGroupExists;
   }
 
   const base::Token tab_id =
@@ -113,5 +123,123 @@
   web_contents_to_tab_id_map_.erase(web_contents);
   model_->RemoveTabFromGroup(saved_guid_, tab_guid);
 
-  return model_->Contains(saved_guid_);
+  return model_->Contains(saved_guid_) ? Liveness::kGroupExists
+                                       : Liveness::kGroupDeleted;
+}
+
+void LocalTabGroupListener::GroupRemovedFromSync() {
+  PauseTracking();
+
+  // Remove every currently tracked tab; this will also close the local group.
+  std::vector<content::WebContents*> contentses;
+  for (auto& [contents, listener] : web_contents_to_tab_id_map_) {
+    contentses.push_back(contents);
+  }
+  for (content::WebContents* const contents : contentses) {
+    RemoveWebContentsFromSync(contents);
+  }
+
+  ResumeTracking();
+}
+
+LocalTabGroupListener::Liveness LocalTabGroupListener::UpdateFromSync() {
+  PauseTracking();
+
+  RemoveLocalWebContentsNotInSavedGroup();
+
+  const SavedTabGroup* const saved_group = model_->Get(saved_guid_);
+  TabStripModel* const tab_strip_model =
+      SavedTabGroupUtils::GetBrowserWithTabGroupId(local_id_)
+          ->tab_strip_model();
+
+  std::unordered_map<base::Token, content::WebContents*, base::TokenHash>
+      token_to_contents_map;
+  for (auto& [contents, listener] : web_contents_to_tab_id_map_) {
+    token_to_contents_map[listener.token()] = contents;
+  }
+
+  // Add, navigate, and reorder local tabs to match saved tabs.
+  const gfx::Range group_index_range =
+      tab_strip_model->group_model()->GetTabGroup(local_id_)->ListTabs();
+  CHECK_LE(group_index_range.length(), saved_group->saved_tabs().size());
+
+  // Parallel iterate over saved tabs and local indices. For each saved tab and
+  // index, ensure the corresponding local tab is at that index and in the
+  // correct state.
+  int next_index_in_tab_strip = group_index_range.start();
+  for (const SavedTabGroupTab& saved_tab : saved_group->saved_tabs()) {
+    content::WebContents* const contents =
+        saved_tab.local_tab_id().has_value()
+            ? token_to_contents_map[saved_tab.local_tab_id().value()]
+            : nullptr;
+    MatchLocalTabToSavedTab(saved_tab, contents, tab_strip_model,
+                            next_index_in_tab_strip);
+    next_index_in_tab_strip++;
+  }
+
+  ResumeTracking();
+
+  return model_->Contains(saved_guid_) ? Liveness::kGroupExists
+                                       : Liveness::kGroupDeleted;
+}
+
+void LocalTabGroupListener::MatchLocalTabToSavedTab(
+    SavedTabGroupTab saved_tab,
+    content::WebContents* local_tab,
+    TabStripModel* tab_strip_model,
+    int target_index_in_tab_strip) {
+  if (saved_tab.local_tab_id().has_value()) {
+    CHECK(local_tab);
+    // Reorder if needed. This approach corresponds to selection sort.
+    // N.B.: this approach will do N reorders for a tab that was moved N spots
+    // to the left.
+    const int current_index = tab_strip_model->GetIndexOfWebContents(local_tab);
+    CHECK_EQ(local_id_,
+             tab_strip_model->GetTabGroupForTab(current_index).value());
+    tab_strip_model->MoveWebContentsAt(current_index, target_index_in_tab_strip,
+                                       false);
+
+    // Navigate if needed.
+    if (saved_tab.url() != local_tab->GetURL()) {
+      web_contents_to_tab_id_map_.at(local_tab).NavigateToUrl(saved_tab.url());
+    }
+  } else {
+    OpenWebContentsFromSync(
+        saved_tab, SavedTabGroupUtils::GetBrowserWithTabGroupId(local_id_),
+        target_index_in_tab_strip);
+  }
+}
+
+void LocalTabGroupListener::OpenWebContentsFromSync(SavedTabGroupTab tab,
+                                                    Browser* browser,
+                                                    int index_in_tabstrip) {
+  content::WebContents* opened_contents = SavedTabGroupUtils::OpenTabInBrowser(
+      tab.url(), browser, browser->profile(),
+      WindowOpenDisposition::NEW_BACKGROUND_TAB, index_in_tabstrip, local_id_);
+
+  // Listen to navigations.
+  base::Token token = base::Token::CreateRandom();
+  tab.SetLocalTabID(token);
+  model_->UpdateTabInGroup(tab.saved_group_guid(), tab);
+  web_contents_to_tab_id_map_.try_emplace(opened_contents, opened_contents,
+                                          token, model_);
+}
+
+void LocalTabGroupListener::RemoveLocalWebContentsNotInSavedGroup() {
+  const SavedTabGroup* const saved_group = model_->Get(saved_guid_);
+  const std::vector<content::WebContents*> web_contentses_in_local_group =
+      SavedTabGroupUtils::GetWebContentsesInGroup(local_id_);
+  for (content::WebContents* const contents : web_contentses_in_local_group) {
+    const auto& it = web_contents_to_tab_id_map_.find(contents);
+    CHECK(it != web_contents_to_tab_id_map_.end());
+    if (!saved_group->ContainsTab(it->second.token())) {
+      RemoveWebContentsFromSync(contents);
+    }
+  }
+}
+
+void LocalTabGroupListener::RemoveWebContentsFromSync(
+    content::WebContents* contents) {
+  contents->Close();
+  web_contents_to_tab_id_map_.erase(contents);
 }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.h b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.h
index 4a373bd..58694d7f 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/local_tab_group_listener.h
@@ -17,6 +17,7 @@
 class SavedTabGroup;
 class SavedTabGroupModel;
 class TabStripModel;
+class Browser;
 
 // Keeps a saved tab group up to date as it's changed locally.
 class LocalTabGroupListener {
@@ -39,17 +40,29 @@
   void ResumeTracking();
 
   // Updates the saved group with the new tab and tracks it for further changes.
-  void AddWebContents(content::WebContents* web_contents,
-                      TabStripModel* tab_strip_model,
-                      int index);
+  void AddWebContentsFromLocal(content::WebContents* web_contents,
+                               TabStripModel* tab_strip_model,
+                               int index);
+
+  // Whether the local and saved groups this listener is connecting still exist.
+  enum class Liveness {
+    kGroupExists,
+    kGroupDeleted,
+  };
 
   // If `web_contents` is in this listener's local tab group, removes it from
-  // the saved tab group and stops tracking it. Returns true if the saved group
-  // still exists, and false if removing `web_contents` also removed the group
-  // (by emptying it). In the latter case, callers should destroy this listener.
-  [[nodiscard]] bool RemoveWebContentsIfPresent(
+  // the saved tab group and stops tracking it. Returns whether the local group
+  // this is tracking still exists after `web_contents`' removal.
+  [[nodiscard]] Liveness MaybeRemoveWebContentsFromLocal(
       content::WebContents* web_contents);
 
+  // The saved group was deleted, so close the local group.
+  void GroupRemovedFromSync();
+
+  // Updates the local group to match the current state of the saved group.
+  // Returns whether the local group still exists after this update.
+  [[nodiscard]] Liveness UpdateFromSync();
+
   // Testing Accessors.
   std::unordered_map<content::WebContents*, SavedTabGroupWebContentsListener>&
   GetWebContentsTokenMapForTesting() {
@@ -57,6 +70,18 @@
   }
 
  private:
+  // Updates `local_tab` to match `saved_tab`, and ensures it is at
+  // `target_index_in_tab_strip` in `tab_strip_model`.
+  void MatchLocalTabToSavedTab(SavedTabGroupTab saved_tab,
+                               content::WebContents* local_tab,
+                               TabStripModel* tab_strip_model,
+                               int target_index_in_tab_strip);
+  void OpenWebContentsFromSync(SavedTabGroupTab tab,
+                               Browser* browser,
+                               int index_in_tabstrip);
+  // Removes any tabs in the local group that aren't in the saved group.
+  void RemoveLocalWebContentsNotInSavedGroup();
+  void RemoveWebContentsFromSync(content::WebContents* contents);
   const SavedTabGroup* saved_group() const { return model_->Get(saved_guid_); }
 
   // Whether local tab group changes will be ignored (`paused_` is true) or
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 c0bc74c..857e36c 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
@@ -45,12 +45,6 @@
       listener_(model(), profile),
       bridge_(model(), GetStoreFactory(), CreateChangeProcessor()) {
   model()->AddObserver(this);
-
-  // Perform the necessary setup, if the model is already loaded before we start
-  // observing it. Otherwise, the model will notify us when it has loaded.
-  if (model()->is_loaded()) {
-    SavedTabGroupModelLoaded();
-  }
 }
 
 SavedTabGroupKeyedService::~SavedTabGroupKeyedService() {
@@ -66,13 +60,22 @@
 void SavedTabGroupKeyedService::StoreLocalToSavedId(
     const base::Uuid& saved_guid,
     const tab_groups::TabGroupId local_group_id) {
-  const SavedTabGroup* const group = model()->Get(local_group_id);
-  if (model()->is_loaded() && group->saved_guid() == saved_guid) {
+  // Avoid linking SavedTabGroups that are already open.
+  const SavedTabGroup* const group = model()->Get(saved_guid);
+  if (group && group->local_group_id().has_value()) {
     return;
   }
 
-  saved_guid_to_local_group_id_mapping_.emplace_back(saved_guid,
-                                                     local_group_id);
+  // The model could already be loaded when restoring groups from a previously
+  // crashed session / window. This means we will have to manually trigger the
+  // local to saved group linking.
+  if (model()->is_loaded()) {
+    model_.OnGroupOpenedInTabStrip(saved_guid, local_group_id);
+    ConnectLocalTabGroup(local_group_id, saved_guid);
+  } else {
+    saved_guid_to_local_group_id_mapping_.emplace_back(saved_guid,
+                                                       local_group_id);
+  }
 }
 
 void SavedTabGroupKeyedService::OpenSavedTabGroupInBrowser(
@@ -315,16 +318,21 @@
     return;
   }
 
-  if (tab_guid.has_value()) {
-    // TODO(dljames): Update tabs in the tabstrip if the respective group is
-    // open with the updated tab metadata. Figure out if the tab should be
-    // added, removed, or updated based on the data in saved_group.
-    NOTIMPLEMENTED();
-  } else {
-    // Update the visual data of the saved group if it exists and is open in
-    // the tabstrip.
-    UpdateGroupVisualData(group_guid, saved_group->local_group_id().value());
+  // Update the local group's metadata to match the saved group's.
+  UpdateGroupVisualData(group_guid, saved_group->local_group_id().value());
+  // Update the local group's contents to match the saved group's.
+  listener_.UpdateLocalGroupFromSync(saved_group->local_group_id().value());
+}
+
+void SavedTabGroupKeyedService::SavedTabGroupRemovedFromSync(
+    const SavedTabGroup* removed_group) {
+  // Do nothing if `removed_group` is not open in the tabstrip.
+  if (!removed_group->local_group_id().has_value()) {
+    return;
   }
+
+  // Update the local group's contents to match the saved group's.
+  listener_.RemoveLocalGroupFromSync(removed_group->local_group_id().value());
 }
 
 const TabStripModel* SavedTabGroupKeyedService::GetTabStripModelWithTabGroupId(
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 b0249dfd..652de2d 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
@@ -54,6 +54,7 @@
 
   // SavedTabGroupModelObserver
   void SavedTabGroupModelLoaded() override;
+  void SavedTabGroupRemovedFromSync(const SavedTabGroup* group) override;
   void SavedTabGroupUpdatedFromSync(
       const base::Uuid& group_guid,
       const absl::optional<base::Uuid>& tab_guid) override;
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc
index 12c448e4..5271ed6 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc
@@ -368,3 +368,139 @@
   EXPECT_EQ(tab_group->visual_data()->title(), retrieved_saved_group->title());
   EXPECT_EQ(tab_group->visual_data()->color(), retrieved_saved_group->color());
 }
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest, NewTabFromSyncOpensInLocalGroup) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with one tab.
+  ASSERT_EQ(0, tabstrip->count());
+  AddTabToBrowser(browser, 0);
+  ASSERT_EQ(1, tabstrip->count());
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0});
+  service()->SaveGroup(group_id);
+  const base::Uuid saved_group_id =
+      service()->model()->Get(group_id)->saved_guid();
+
+  // Add a tab to the saved group.
+  const SavedTabGroupTab added_tab(GURL("chrome://newtab"), u"New Tab",
+                                   saved_group_id);
+  service()->model()->AddTabToGroup(saved_group_id, added_tab, false);
+
+  // Tab should have opened in local group too.
+  EXPECT_EQ(2, tabstrip->count());
+  EXPECT_EQ(
+      2u, tabstrip->group_model()->GetTabGroup(group_id)->ListTabs().length());
+}
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest,
+       NavigateTabFromSyncNavigatesLocalTab) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with one tab.
+  ASSERT_EQ(0, tabstrip->count());
+  AddTabToBrowser(browser, 0);
+  ASSERT_EQ(1, tabstrip->count());
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0});
+  service()->SaveGroup(group_id);
+  const SavedTabGroup* const saved_group = service()->model()->Get(group_id);
+  const base::Uuid saved_tab_id =
+      saved_group->saved_tabs().at(0).saved_tab_guid();
+
+  // Navigate the saved tab.
+  const GURL url = GURL("https://www.example.com");
+  SavedTabGroupTab navigated_tab = *saved_group->GetTab(saved_tab_id);
+  navigated_tab.SetURL(url);
+  navigated_tab.SetTitle(u"Example Page");
+  std::unique_ptr<sync_pb::SavedTabGroupSpecifics> specific =
+      navigated_tab.ToSpecifics();
+  service()->model()->MergeTab(*specific);
+
+  // The local tab should have navigated too.
+  EXPECT_EQ(tabstrip->GetWebContentsAt(0)->GetURL(), url);
+}
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest, RemoveTabFromSyncRemovesLocalTab) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with two tabs.
+  AddTabToBrowser(browser, 0);
+  AddTabToBrowser(browser, 1);
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0, 1});
+  service()->SaveGroup(group_id);
+  const SavedTabGroup* const saved_group = service()->model()->Get(group_id);
+
+  // Remove one tab from the saved group.
+  service()->model()->RemoveTabFromGroup(
+      saved_group->saved_guid(),
+      saved_group->saved_tabs().at(0).saved_tab_guid(), false);
+
+  // It should have been removed from the local group too.
+  EXPECT_EQ(1, tabstrip->count());
+  EXPECT_EQ(
+      1u, tabstrip->group_model()->GetTabGroup(group_id)->ListTabs().length());
+}
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest,
+       RemoveLastTabFromSyncRemovesLocalTabAndLocalGroup) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with one tab.
+  AddTabToBrowser(browser, 0);
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0});
+  service()->SaveGroup(group_id);
+  const SavedTabGroup* const saved_group = service()->model()->Get(group_id);
+  // Add an extra tab so closing the grouped tab doesn't close the browser.
+  AddTabToBrowser(browser, 1);
+
+  // Remove the only tab from the saved group.
+  service()->model()->RemoveTabFromGroup(
+      saved_group->saved_guid(),
+      saved_group->saved_tabs().at(0).saved_tab_guid(), false);
+
+  // It should have been removed from the local group too.
+  EXPECT_EQ(1, tabstrip->count());
+  // The local group should also have been closed, since it's now empty.
+  EXPECT_FALSE(tabstrip->group_model()->ContainsTabGroup(group_id));
+}
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest,
+       RemoveGroupFromSyncRemovesLocalTabAndLocalGroup) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with one tab.
+  AddTabToBrowser(browser, 0);
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0});
+  service()->SaveGroup(group_id);
+  const base::Uuid saved_group_id =
+      service()->model()->Get(group_id)->saved_guid();
+  // Add an extra tab so closing the grouped tab doesn't close the browser.
+  AddTabToBrowser(browser, 1);
+
+  // Remove the saved group.
+  service()->model()->RemovedFromSync(saved_group_id);
+
+  // The local group should have been closed.
+  EXPECT_FALSE(tabstrip->group_model()->ContainsTabGroup(group_id));
+  // The local tab in the group should have been removed too.
+  EXPECT_EQ(1, tabstrip->count());
+}
+
+TEST_F(SavedTabGroupKeyedServiceUnitTest, ReorderTabFromSyncReordersLocalTab) {
+  Browser* const browser = AddBrowser();
+  TabStripModel* const tabstrip = browser->tab_strip_model();
+
+  // Create a saved tab group with two tabs.
+  AddTabToBrowser(browser, 0);
+  AddTabToBrowser(browser, 1);
+  const tab_groups::TabGroupId group_id = tabstrip->AddToNewGroup({0, 1});
+  service()->SaveGroup(group_id);
+  const base::Uuid saved_group_id =
+      service()->model()->Get(group_id)->saved_guid();
+
+  // TODO Fill out this test once swap tabs from sync is implemented
+}
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 ab1dfacc..d771b02 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
@@ -64,7 +64,8 @@
   // Remove `contents` from its current saved group, if it's in one.
   for (auto& [local_group_id, listener] : local_tab_group_listeners_) {
     if (local_group_id != new_local_group_id) {
-      if (!listener.RemoveWebContentsIfPresent(contents)) {
+      if (listener.MaybeRemoveWebContentsFromLocal(contents) ==
+          LocalTabGroupListener::Liveness::kGroupDeleted) {
         // If this emptied the group, the saved group was removed, so we must
         // stop listening to `local_group_id`.
         DisconnectLocalTabGroup(local_group_id);
@@ -83,7 +84,8 @@
     const Browser* const browser = SavedTabGroupUtils::GetBrowserWithTabGroupId(
         new_local_group_id.value());
     CHECK(browser);
-    listener.AddWebContents(contents, browser->tab_strip_model(), index);
+    listener.AddWebContentsFromLocal(contents, browser->tab_strip_model(),
+                                     index);
   }
 }
 
@@ -162,6 +164,28 @@
   local_tab_group_listeners_.erase(tab_group_id);
 }
 
+void SavedTabGroupModelListener::RemoveLocalGroupFromSync(
+    tab_groups::TabGroupId local_group_id) {
+  if (!local_tab_group_listeners_.contains(local_group_id)) {
+    return;
+  }
+
+  local_tab_group_listeners_.at(local_group_id).GroupRemovedFromSync();
+  DisconnectLocalTabGroup(local_group_id);
+}
+
+void SavedTabGroupModelListener::UpdateLocalGroupFromSync(
+    tab_groups::TabGroupId local_group_id) {
+  if (!local_tab_group_listeners_.contains(local_group_id)) {
+    return;
+  }
+
+  if (local_tab_group_listeners_.at(local_group_id).UpdateFromSync() ==
+      LocalTabGroupListener::Liveness::kGroupDeleted) {
+    DisconnectLocalTabGroup(local_group_id);
+  }
+}
+
 void SavedTabGroupModelListener::OnBrowserAdded(Browser* browser) {
   if (profile_ != browser->profile()) {
     return;
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 53abbbe3..5905f7b 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
@@ -49,6 +49,14 @@
   // `tab_group_id` when the local group changes.
   void DisconnectLocalTabGroup(tab_groups::TabGroupId tab_group_id);
 
+  // The saved group corresponding to `local_group_id` was removed, so we must
+  // remove the local group to match.
+  void RemoveLocalGroupFromSync(tab_groups::TabGroupId local_group_id);
+
+  // Updates the local group with id `local_group_id` to match the current state
+  // of the saved tab group, if it is open locally.
+  void UpdateLocalGroupFromSync(tab_groups::TabGroupId local_group_id);
+
   // BrowserListObserver:
   void OnBrowserAdded(Browser* browser) override;
   void OnBrowserRemoved(Browser* browser) override;
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc
index 56b84a3..852684d 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc
@@ -28,10 +28,14 @@
     const GURL& url,
     Browser* browser,
     Profile* profile,
-    WindowOpenDisposition disposition) {
+    WindowOpenDisposition disposition,
+    absl::optional<int> tabstrip_index,
+    absl::optional<tab_groups::TabGroupId> local_group_id) {
   NavigateParams params(profile, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
   params.disposition = disposition;
   params.browser = browser;
+  params.tabstrip_index = tabstrip_index.value_or(params.tabstrip_index);
+  params.group = local_group_id;
   base::WeakPtr<content::NavigationHandle> handle = Navigate(&params);
   return handle ? handle->GetWebContents() : nullptr;
 }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h
index 0ceafd8..ae835ca9 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h
@@ -33,7 +33,9 @@
       const GURL& url,
       Browser* browser,
       Profile* profile,
-      WindowOpenDisposition disposition);
+      WindowOpenDisposition disposition,
+      absl::optional<int> tabstrip_index = absl::nullopt,
+      absl::optional<tab_groups::TabGroupId> local_group_id = absl::nullopt);
 
   // Returns the Browser that contains a local group with id `group_id`.
   static Browser* GetBrowserWithTabGroupId(tab_groups::TabGroupId group_id);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.cc
index 0339fbe..f7d6b15 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.cc
@@ -22,6 +22,15 @@
 
 SavedTabGroupWebContentsListener::~SavedTabGroupWebContentsListener() = default;
 
+void SavedTabGroupWebContentsListener::NavigateToUrl(const GURL& url) {
+  content::NavigationHandle* navigation_handle =
+      web_contents()
+          ->GetController()
+          .LoadURLWithParams(content::NavigationController::LoadURLParams(url))
+          .get();
+  handle_from_sync_update_ = navigation_handle;
+}
+
 void SavedTabGroupWebContentsListener::DidFinishNavigation(
     content::NavigationHandle* navigation_handle) {
   ui::PageTransition page_transition = navigation_handle->GetPageTransition();
@@ -31,6 +40,14 @@
     return;
   }
 
+  // If the navigation was the result of a sync update we don't want to update
+  // the SavedTabGroupModel.
+  if (navigation_handle == handle_from_sync_update_) {
+    return;
+  } else {
+    handle_from_sync_update_ = nullptr;
+  }
+
   SavedTabGroup* group = model_->GetGroupContainingTab(token_);
   CHECK(group);
 
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.h
index ef976b39..2256c4e 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_web_contents_listener.h
@@ -26,6 +26,8 @@
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
 
+  void NavigateToUrl(const GURL& url);
+
   base::Token token() const { return token_; }
   content::WebContents* web_contents() const { return web_contents_; }
 
@@ -33,6 +35,10 @@
   const base::Token token_;
   const raw_ptr<content::WebContents> web_contents_;
   const raw_ptr<SavedTabGroupModel> model_;
+
+  // The NavigationHandle that resulted from the last sync update. Ignored by
+  // `DidFinishNavigation` to prevent synclones.
+  raw_ptr<content::NavigationHandle> handle_from_sync_update_ = nullptr;
 };
 
 #endif  // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_WEB_CONTENTS_LISTENER_H_
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container_interactive_uitest.cc
index 5bb5e8b4..6a3b7451 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container_interactive_uitest.cc
@@ -11,6 +11,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "build/build_config.h"
+#include "chrome/browser/extensions/browsertest_util.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
 #include "chrome/browser/extensions/extension_action_runner.h"
 #include "chrome/browser/extensions/extension_context_menu_model.h"
@@ -57,30 +58,6 @@
 
 constexpr char kInjectionSucceededMessage[] = "injection succeeded";
 
-class BlockedActionWaiter
-    : public extensions::ExtensionActionRunner::TestObserver {
- public:
-  explicit BlockedActionWaiter(extensions::ExtensionActionRunner* runner)
-      : runner_(runner), run_loop_(std::make_unique<base::RunLoop>()) {
-    runner_->set_observer_for_testing(this);
-  }
-  BlockedActionWaiter(const BlockedActionWaiter&) = delete;
-  BlockedActionWaiter& operator=(const BlockedActionWaiter&) = delete;
-  ~BlockedActionWaiter() { runner_->set_observer_for_testing(nullptr); }
-
-  void WaitAndReset() {
-    run_loop_->Run();
-    run_loop_ = std::make_unique<base::RunLoop>();
-  }
-
- private:
-  // ExtensionActionRunner::TestObserver:
-  void OnBlockedActionAdded() override { run_loop_->Quit(); }
-
-  raw_ptr<extensions::ExtensionActionRunner> runner_;
-  std::unique_ptr<base::RunLoop> run_loop_;
-};
-
 views::Widget* CreateBubble(views::View* anchor_point) {
   std::unique_ptr<ui::DialogModel> dialog_model =
       ui::DialogModel::Builder().SetTitle(u"Title").Build();
@@ -754,7 +731,6 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   extensions::ExtensionActionRunner* runner =
       extensions::ExtensionActionRunner::GetForWebContents(web_contents);
-  BlockedActionWaiter blocked_action_waiter(runner);
   extensions::PermissionsManager* permissions_manager =
       extensions::PermissionsManager::Get(profile());
 
@@ -762,10 +738,12 @@
   GURL urlA = embedded_test_server()->GetURL("example.com", "/title1.html");
   {
     content::TestNavigationObserver observer(web_contents);
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        runner);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), urlA));
     EXPECT_TRUE(observer.last_navigation_succeeded());
 
-    blocked_action_waiter.WaitAndReset();
+    blocked_action_waiter.Wait();
     EXPECT_TRUE(runner->WantsToRun(extension()));
     EXPECT_FALSE(
         permissions_manager->HasGrantedHostPermission(*extension(), urlA));
@@ -804,10 +782,12 @@
   GURL urlB = embedded_test_server()->GetURL("abc.com", "/title1.html");
   {
     content::TestNavigationObserver observer(web_contents);
+    extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+        runner);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), urlB));
     EXPECT_TRUE(observer.last_navigation_succeeded());
 
-    blocked_action_waiter.WaitAndReset();
+    blocked_action_waiter.Wait();
     EXPECT_TRUE(runner->WantsToRun(extension()));
     EXPECT_FALSE(
         permissions_manager->HasGrantedHostPermission(*extension(), urlB));
@@ -861,7 +841,8 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   extensions::ExtensionActionRunner* runner =
       extensions::ExtensionActionRunner::GetForWebContents(web_contents);
-  BlockedActionWaiter blocked_action_waiter(runner);
+  extensions::browsertest_util::BlockedActionWaiter blocked_action_waiter(
+      runner);
   {
     content::TestNavigationObserver observer(web_contents);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
@@ -869,7 +850,7 @@
   }
 
   // Access to |url| should have been withheld.
-  blocked_action_waiter.WaitAndReset();
+  blocked_action_waiter.Wait();
   EXPECT_TRUE(runner->WantsToRun(extension()));
   extensions::PermissionsManager* permissions_manager =
       extensions::PermissionsManager::Get(profile());
diff --git a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
index 6794622..29ca9093 100644
--- a/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
+++ b/chrome/browser/ui/views/performance_controls/high_efficiency_interactive_ui_test.cc
@@ -670,9 +670,15 @@
           views::Button::ButtonState::STATE_DISABLED));
 }
 
-// Tests Discarding on pages with various types of content
+struct FaviconScreenShotTestConfig {
+  performance_manager::features::DiscardTabTreatmentOptions treatment_option;
+  std::string screenshot_name;
+  std::string cl_number;
+};
+
 class HighEfficiencyFaviconTreatmentTest
-    : public HighEfficiencyInteractiveTest {
+    : public HighEfficiencyInteractiveTest,
+      public testing::WithParamInterface<FaviconScreenShotTestConfig> {
  public:
   HighEfficiencyFaviconTreatmentTest() = default;
   ~HighEfficiencyFaviconTreatmentTest() override = default;
@@ -680,10 +686,8 @@
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeatureWithParameters(
         performance_manager::features::kDiscardedTabTreatment,
-        {{"discard_tab_treatment_option",
-          base::NumberToString(static_cast<int>(
-              performance_manager::features::DiscardTabTreatmentOptions::
-                  kFadeFullsizedFavicon))}});
+        {{"discard_tab_treatment_option", base::NumberToString(static_cast<int>(
+                                              GetParam().treatment_option))}});
 
     animation_mode_reset_ = gfx::AnimationTestApi::SetRichAnimationRenderMode(
         gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED);
@@ -705,16 +709,8 @@
       animation_mode_reset_;
 };
 
-#if BUILDFLAG(IS_WIN)
-#define MAYBE_DimFaviconOnDiscard DISABLED_DimFaviconOnDiscard
-#else
-#define MAYBE_DimFaviconOnDiscard DimFaviconOnDiscard
-#endif
-
-// A tab's favicon should should be dimmed when it is discarded due to high
-// efficiency mode
-IN_PROC_BROWSER_TEST_F(HighEfficiencyFaviconTreatmentTest,
-                       MAYBE_DimFaviconOnDiscard) {
+IN_PROC_BROWSER_TEST_P(HighEfficiencyFaviconTreatmentTest,
+                       FaviconTreatmentOnDiscard) {
   constexpr char kFirstTabFavicon[] = "first_tab_favicon";
 
   RunTestSequence(
@@ -729,5 +725,29 @@
       NameView(kFirstTabFavicon, base::BindLambdaForTesting([&]() {
                  return views::AsViewClass<views::View>(GetTabIcon(0));
                })),
-      Screenshot(kFirstTabFavicon, "TabIcon", "4447439"));
+      Check(base::BindLambdaForTesting([&]() {
+        return GetTabIcon(0)
+            ->GetTabDiscardAnimationForTesting()
+            ->is_animating();
+      })),
+      Do(base::BindLambdaForTesting([&]() {
+        // Force animation to end as it may not have finished progressing
+        // before taking a screenshot
+        GetTabIcon(0)->GetTabDiscardAnimationForTesting()->End();
+      })),
+      Screenshot(kFirstTabFavicon, GetParam().screenshot_name,
+                 GetParam().cl_number));
 }
+
+std::vector<FaviconScreenShotTestConfig> HighEfficiencyTestConfig() {
+  return {{performance_manager::features::DiscardTabTreatmentOptions::
+               kFadeFullsizedFavicon,
+           "FadeFullSizedFaviconOnDiscard", "4492205"},
+          {performance_manager::features::DiscardTabTreatmentOptions::
+               kFadeSmallFaviconWithRing,
+           "FadeSmallFaviconOnDiscard", "4492205"}};
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         HighEfficiencyFaviconTreatmentTest,
+                         testing::ValuesIn(HighEfficiencyTestConfig()));
diff --git a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc
index bd3d4a5..c018fa9 100644
--- a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc
+++ b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc
@@ -6,6 +6,7 @@
 #include <memory>
 #include <string>
 
+#include "base/functional/overloaded.h"
 #include "base/metrics/user_metrics_action.h"
 #include "chrome/browser/browsing_data/cookies_tree_model.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
@@ -187,7 +188,8 @@
   }
 
   std::vector<PageSpecificSiteDataDialogSite> GetAllSites() {
-    std::map<std::string, PageSpecificSiteDataDialogSite> sites_map;
+    std::map<BrowsingDataModel::DataOwner, PageSpecificSiteDataDialogSite>
+        sites_map;
     for (const std::unique_ptr<CookieTreeNode>& node :
          allowed_cookies_tree_model_->GetRoot()->children()) {
       std::string host_name = node->GetDetailedInfo().origin.host();
@@ -208,11 +210,11 @@
     }
     for (const BrowsingDataModel::BrowsingDataEntryView& entry :
          *allowed_browsing_data_model()) {
-      auto existing_site = sites_map.find(*entry.primary_host);
+      const BrowsingDataModel::DataOwner& owner = *entry.data_owner;
+      auto existing_site = sites_map.find(owner);
       if (existing_site == sites_map.end()) {
         sites_map.emplace(
-            *entry.primary_host,
-            CreateSiteFromEntryView(entry, /*from_allowed_model=*/true));
+            owner, CreateSiteFromEntryView(entry, /*from_allowed_model=*/true));
       } else {
         // To display the result entry as fully partitioned, entries from both
         // models have to be partitioned.
@@ -238,7 +240,8 @@
     }
     for (const BrowsingDataModel::BrowsingDataEntryView& entry :
          *blocked_browsing_data_model()) {
-      auto existing_site = sites_map.find(*entry.primary_host);
+      const BrowsingDataModel::DataOwner& owner = *entry.data_owner;
+      auto existing_site = sites_map.find(owner);
       if (existing_site == sites_map.end()) {
         // If there are multiple entries from the same tree, ignore the entry
         // from the blocked tree. It might be caused by partitioned allowed
@@ -246,9 +249,8 @@
         // creating an exception and not reloading the page. Existing site
         // entries doesn't need to be updated as partitioned state isn't
         // relevant for blocked entries.
-        sites_map.emplace(
-            *entry.primary_host,
-            CreateSiteFromEntryView(entry, /*from_allowed_model=*/false));
+        sites_map.emplace(owner, CreateSiteFromEntryView(
+                                     entry, /*from_allowed_model=*/false));
       }
     }
 
@@ -364,15 +366,21 @@
   PageSpecificSiteDataDialogSite CreateSiteFromEntryView(
       const BrowsingDataModel::BrowsingDataEntryView& entry,
       bool from_allowed_model) {
-    GURL current_url = web_contents_->GetVisibleURL();
     // TODO(crbug.com/1271155): BDM provides host name only while
     // CookieTreeModel provides url::Origin. This classes works with
     // url::Origin, so here we convert host name to origin with some assumptions
     // (which might not be true). We should either convert to work only with
     // host names or BDM should return origins.
-    GURL site_url = net::cookie_util::CookieOriginToURL(
-        *entry.primary_host, current_url.SchemeIsCryptographic());
-    return CreateSite(url::Origin::Create(site_url), from_allowed_model,
+    url::Origin entry_origin = absl::visit(
+        base::Overloaded{[&](const std::string& host) {
+                           GURL current_url = web_contents_->GetVisibleURL();
+                           GURL site_url = net::cookie_util::CookieOriginToURL(
+                               host, current_url.SchemeIsCryptographic());
+                           return url::Origin::Create(site_url);
+                         },
+                         [](const url::Origin& origin) { return origin; }},
+        *entry.data_owner);
+    return CreateSite(entry_origin, from_allowed_model,
                       IsBrowsingDataEntryViewFullyPartitioned(entry));
   }
 
diff --git a/chrome/browser/ui/views/tabs/tab_icon.cc b/chrome/browser/ui/views/tabs/tab_icon.cc
index bc0b2a1..a1d9c92a 100644
--- a/chrome/browser/ui/views/tabs/tab_icon.cc
+++ b/chrome/browser/ui/views/tabs/tab_icon.cc
@@ -42,13 +42,51 @@
 
 constexpr int kAttentionIndicatorRadius = 3;
 constexpr int kLoadingAnimationStrokeWidthDp = 2;
-constexpr double kDiscardedFaviconFinalOpacity = 0.3;
+constexpr float kDiscardRingStrokeWidthDp = 1.5;
+
+// Discard Ring Segments
+constexpr int kNumSmallSegments = 4;
+constexpr int kNumSpacingSegments = kNumSmallSegments + 1;
+constexpr int kLargeSegmentSweepAngle = 160;
+
+// Split the remaining space in half so that half is allocated for the small
+// segmant of the ring and the other half is for the spacing between segments
+constexpr int kAllocatedSpace = (360 - kLargeSegmentSweepAngle) / 2;
+constexpr int kSpacingSweepAngle = kAllocatedSpace / kNumSpacingSegments;
+constexpr int kSmallSegmentSweepAngle = kAllocatedSpace / kNumSmallSegments;
 
 bool NetworkStateIsAnimated(TabNetworkState network_state) {
   return network_state != TabNetworkState::kNone &&
          network_state != TabNetworkState::kError;
 }
 
+// Paints arc starting at `start_angle` with a `sweep` in degrees.
+// A starting angle of 0 means that the arc starts on the right side of `bounds`
+// and continues drawing the arc in a clockwise direction for `sweep` degrees
+void PaintArc(gfx::Canvas* canvas,
+              const gfx::Rect& bounds,
+              SkColor color,
+              SkScalar start_angle,
+              SkScalar sweep,
+              float opacity) {
+  gfx::RectF oval(bounds);
+  // Inset by half the stroke width to make sure the whole arc is inside
+  // the visible rect.
+  const double inset = kDiscardRingStrokeWidthDp / 2.0;
+  oval.Inset(inset);
+
+  SkPath path;
+  path.arcTo(RectFToSkRect(oval), start_angle, sweep, true);
+
+  cc::PaintFlags flags;
+  flags.setColor(color);
+  flags.setStrokeCap(cc::PaintFlags::kRound_Cap);
+  flags.setStrokeWidth(kDiscardRingStrokeWidthDp);
+  flags.setStyle(cc::PaintFlags::kStroke_Style);
+  flags.setAntiAlias(true);
+  flags.setAlphaf(opacity);
+  canvas->DrawPath(path, flags);
+}
 }  // namespace
 
 // Helper class that manages the favicon crash animation.
@@ -101,7 +139,10 @@
           performance_manager::features::kDiscardedTabTreatment)) {
     discard_tab_treatment_option_ =
         static_cast<performance_manager::features::DiscardTabTreatmentOptions>(
-            performance_manager::features::kDiscardedTabTreatmenOption.Get());
+            performance_manager::features::kDiscardedTabTreatmentOption.Get());
+
+    discard_tab_icon_final_opacity_ =
+        performance_manager::features::kDiscardedTabTreatmentOpacity.Get();
   }
 
   if (!gfx::Animation::ShouldRenderRichAnimation()) {
@@ -118,7 +159,7 @@
   SetIcon(data.favicon, data.should_themify_favicon);
   SetNetworkState(data.network_state);
   SetCrashed(data.IsCrashed());
-  SetDiscarded(data.is_tab_discarded, data.should_show_discard_status);
+  SetDiscarded(data.should_show_discard_status);
   has_tab_renderer_data_ = true;
 
   const bool showing_load = GetShowingLoadingAnimation();
@@ -175,6 +216,10 @@
     SchedulePaint();
 }
 
+gfx::LinearAnimation* TabIcon::GetTabDiscardAnimationForTesting() {
+  return &tab_discard_animation_;
+}
+
 void TabIcon::OnPaint(gfx::Canvas* canvas) {
   // Compute the bounds adjusted for the hiding fraction.
   gfx::Rect contents_bounds = GetContentsBounds();
@@ -193,6 +238,11 @@
   if (!GetShowingLoadingAnimation() && GetShowingAttentionIndicator() &&
       !should_display_crashed_favicon_) {
     PaintAttentionIndicatorAndIcon(canvas, GetIconToPaint(), icon_bounds);
+  } else if (discard_tab_treatment_option_ ==
+                 performance_manager::features::DiscardTabTreatmentOptions::
+                     kFadeSmallFaviconWithRing &&
+             was_discard_indicator_shown_) {
+    PaintDiscardRingAndIcon(canvas, GetIconToPaint(), icon_bounds);
   } else {
     MaybePaintFavicon(canvas, GetIconToPaint(), icon_bounds);
   }
@@ -209,17 +259,6 @@
 }
 
 void TabIcon::AnimationProgressed(const gfx::Animation* animation) {
-  if (animation == &tab_discard_animation_ &&
-      discard_tab_treatment_option_ ==
-          performance_manager::features::DiscardTabTreatmentOptions::
-              kFadeFullsizedFavicon) {
-    const double opacity = gfx::Tween::DoubleValueBetween(
-        animation->GetCurrentValue(), 1.0, kDiscardedFaviconFinalOpacity);
-    gfx::ImageSkia favicon =
-        !themed_favicon_.isNull() ? themed_favicon_ : favicon_;
-    translucent_icon_ =
-        gfx::ImageSkiaOperations::CreateTransparentImage(favicon, opacity);
-  }
   SchedulePaint();
 }
 
@@ -262,6 +301,42 @@
   canvas->DrawCircle(circle_center, kAttentionIndicatorRadius, indicator_flags);
 }
 
+void TabIcon::PaintDiscardRingAndIcon(gfx::Canvas* canvas,
+                                      const gfx::ImageSkia& icon,
+                                      const gfx::Rect& bounds) {
+  double discard_animation_value = tab_discard_animation_.GetCurrentValue();
+
+  // Fades out the full sized favicon when animating
+  if (tab_discard_animation_.is_animating()) {
+    cc::PaintFlags opacity_flag;
+    opacity_flag.setAlphaf(
+        gfx::Tween::FloatValueBetween(discard_animation_value, 1.0, 0));
+    canvas->DrawImageInt(icon, 0, 0, bounds.width(), bounds.height(),
+                         bounds.x(), bounds.y(), bounds.width(),
+                         bounds.height(), false, opacity_flag);
+  }
+
+  // Fades in the discard ring and smaller favicon
+  MaybePaintFavicon(canvas, icon, bounds);
+
+  // Painting Discard Ring
+  // Draw the large segment centered on the left side.
+  const int large_segment_start_angle = 180 - kLargeSegmentSweepAngle / 2;
+  PaintArc(canvas, bounds, SK_ColorGRAY, large_segment_start_angle,
+           kLargeSegmentSweepAngle, discard_animation_value);
+
+  // Draw the small segments evenly spaced around the rest of the ring.
+  const int small_segments_start_angle =
+      180 + (kLargeSegmentSweepAngle / 2) + kSpacingSweepAngle;
+  for (int i = 0; i < kNumSmallSegments; i++) {
+    const int start_angle =
+        small_segments_start_angle +
+        (i * (kSmallSegmentSweepAngle + kSpacingSweepAngle));
+    PaintArc(canvas, bounds, SK_ColorGRAY, start_angle % 360,
+             kSmallSegmentSweepAngle, discard_animation_value);
+  }
+}
+
 void TabIcon::PaintLoadingAnimation(gfx::Canvas* canvas, gfx::Rect bounds) {
   TRACE_EVENT0("views", "TabIcon::PaintLoadingAnimation");
 
@@ -297,12 +372,6 @@
     return crashed_icon_;
   }
 
-  if (!translucent_icon_.isNull() &&
-      discard_tab_treatment_option_ !=
-          performance_manager::features::DiscardTabTreatmentOptions::kNone) {
-    return translucent_icon_;
-  }
-
   return themed_favicon_.isNull() ? favicon_ : themed_favicon_;
 }
 
@@ -325,9 +394,15 @@
 
   std::unique_ptr<gfx::ScopedCanvas> scoped_canvas;
   bool use_scale_filter = false;
+  bool show_discard_ring_treatment =
+      was_discard_indicator_shown_ &&
+      discard_tab_treatment_option_ ==
+          performance_manager::features::DiscardTabTreatmentOptions::
+              kFadeSmallFaviconWithRing;
 
   if (GetShowingLoadingAnimation() ||
-      favicon_fade_in_animation_.is_animating()) {
+      favicon_fade_in_animation_.is_animating() ||
+      show_discard_ring_treatment) {
     scoped_canvas = std::make_unique<gfx::ScopedCanvas>(canvas);
     use_scale_filter = true;
     // The favicon is initially inset with the width of the loading-animation
@@ -367,9 +442,23 @@
     canvas->Translate(gfx::Vector2d(-bounds.x(), -bounds.y()));
   }
 
+  cc::PaintFlags opacity_flag;
+  if (show_discard_ring_treatment) {
+    opacity_flag.setAlphaf(
+        gfx::Tween::FloatValueBetween(tab_discard_animation_.GetCurrentValue(),
+                                      0, discard_tab_icon_final_opacity_));
+  } else if (was_discard_indicator_shown_ &&
+             discard_tab_treatment_option_ ==
+                 performance_manager::features::DiscardTabTreatmentOptions::
+                     kFadeFullsizedFavicon) {
+    opacity_flag.setAlphaf(
+        gfx::Tween::FloatValueBetween(tab_discard_animation_.GetCurrentValue(),
+                                      1.0, discard_tab_icon_final_opacity_));
+  }
+
   canvas->DrawImageInt(icon, 0, 0, bounds.width(), bounds.height(), bounds.x(),
                        bounds.y(), bounds.width(), bounds.height(),
-                       use_scale_filter);
+                       use_scale_filter, opacity_flag);
 }
 
 bool TabIcon::GetNonDefaultFavicon() const {
@@ -394,18 +483,15 @@
   SchedulePaint();
 }
 
-void TabIcon::SetDiscarded(bool is_tab_discarded, bool show_discard_status) {
-  if (was_tab_discarded_ != is_tab_discarded) {
-    if (discard_tab_treatment_option_ ==
-        performance_manager::features::DiscardTabTreatmentOptions::
-            kFadeFullsizedFavicon) {
-      was_tab_discarded_ = is_tab_discarded;
-      if (show_discard_status) {
-        tab_discard_animation_.Start();
-      } else {
-        translucent_icon_ = gfx::ImageSkia();
-        tab_discard_animation_.Stop();
-      }
+void TabIcon::SetDiscarded(bool should_show_discard_status) {
+  if (was_discard_indicator_shown_ != should_show_discard_status &&
+      discard_tab_treatment_option_ !=
+          performance_manager::features::DiscardTabTreatmentOptions::kNone) {
+    was_discard_indicator_shown_ = should_show_discard_status;
+    if (should_show_discard_status) {
+      tab_discard_animation_.Start();
+    } else {
+      tab_discard_animation_.Stop();
     }
   }
 }
diff --git a/chrome/browser/ui/views/tabs/tab_icon.h b/chrome/browser/ui/views/tabs/tab_icon.h
index 25ded5da..d0244f0 100644
--- a/chrome/browser/ui/views/tabs/tab_icon.h
+++ b/chrome/browser/ui/views/tabs/tab_icon.h
@@ -69,6 +69,8 @@
   // strip in order to keep the throbbers in sync.
   void StepLoadingAnimation(const base::TimeDelta& elapsed_time);
 
+  gfx::LinearAnimation* GetTabDiscardAnimationForTesting();
+
  private:
   class CrashAnimation;
   friend CrashAnimation;
@@ -87,6 +89,11 @@
                                       const gfx::ImageSkia& icon,
                                       const gfx::Rect& bounds);
 
+  // Paints a dimmed and shrunken favicon surrounded by the discard ring
+  void PaintDiscardRingAndIcon(gfx::Canvas* canvas,
+                               const gfx::ImageSkia& icon,
+                               const gfx::Rect& bounds);
+
   // Paint either the indeterimate throbber or progress indicator according to
   // current tab state.
   void PaintLoadingAnimation(gfx::Canvas* canvas, gfx::Rect bounds);
@@ -104,7 +111,7 @@
   void SetIcon(const gfx::ImageSkia& icon, bool should_themify_favicon);
 
   // Start or stops the favicon fade animation for discard tabs
-  void SetDiscarded(bool is_tab_discarded, bool show_discard_status);
+  void SetDiscarded(bool show_discard_status);
 
   // For certain types of tabs the loading animation is not desired so the
   // caller can set inhibit_loading_animation to true. When false, the loading
@@ -162,17 +169,15 @@
   // fade out
   gfx::LinearAnimation tab_discard_animation_;
 
-  // When the favicon is partially translucent to signal that the tab has been
-  // discarded. If this isNull(), then the favicon is not translucent and
-  // favicon_ or themed_favicon_ should be used instead.
-  gfx::ImageSkia translucent_icon_;
-
-  bool was_tab_discarded_ = false;
+  bool was_discard_indicator_shown_ = false;
 
   performance_manager::features::DiscardTabTreatmentOptions
       discard_tab_treatment_option_ =
           performance_manager::features::DiscardTabTreatmentOptions::kNone;
 
+  // Favicon opacity after the discard animation completes
+  double discard_tab_icon_final_opacity_ = 1.0;
+
   // Crash animation (in place of favicon). Lazily created since most of the
   // time it will be unneeded.
   std::unique_ptr<CrashAnimation> crash_animation_;
diff --git a/chrome/browser/ui/webui/BUILD.gn b/chrome/browser/ui/webui/BUILD.gn
index 05b2977..9a9104b 100644
--- a/chrome/browser/ui/webui/BUILD.gn
+++ b/chrome/browser/ui/webui/BUILD.gn
@@ -68,6 +68,8 @@
       "//ash/webui/guest_os_installer:guest_os_installer",
       "//ash/webui/help_app_ui",
       "//ash/webui/os_feedback_ui",
+      "//ash/webui/scanning:scanning",
+      "//ash/webui/shimless_rma:shimless_rma",
       "//ash/webui/shortcut_customization_ui",
       "//ash/webui/system_extensions_internals_ui:system_extensions_internals_ui",
       "//chrome/browser/ash",
diff --git a/chrome/browser/ui/webui/ash/edu_account_login_handler.cc b/chrome/browser/ui/webui/ash/edu_account_login_handler.cc
index 771f956..2ca92a2 100644
--- a/chrome/browser/ui/webui/ash/edu_account_login_handler.cc
+++ b/chrome/browser/ui/webui/ash/edu_account_login_handler.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h"
 #include "chromeos/ash/components/account_manager/account_manager_factory.h"
 #include "components/account_manager_core/chromeos/account_manager.h"
 #include "components/image_fetcher/core/image_fetcher_service.h"
@@ -200,7 +199,7 @@
 
   list_family_members_fetcher_ = FetchListFamilyMembers(
       *IdentityManagerFactory::GetForProfile(profile),
-      profile->GetURLLoaderFactory(), KidsManagementService::GetEndpointUrl(),
+      profile->GetURLLoaderFactory(),
       base::BindOnce(
           &EduAccountLoginHandler::OnListFamilyMembersResponse,
           base::Unretained(this)));  // Unretained(.) is safe because `this`
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 7358ada1..469bcb8 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -214,10 +214,6 @@
 #include "ash/webui/print_management/url_constants.h"
 #include "ash/webui/projector_app/public/cpp/projector_app_constants.h"  // nogncheck
 #include "ash/webui/projector_app/trusted_projector_ui.h"
-#include "ash/webui/scanning/scanning_ui.h"
-#include "ash/webui/scanning/url_constants.h"
-#include "ash/webui/shimless_rma/shimless_rma.h"
-#include "ash/webui/shimless_rma/url_constants.h"
 #include "ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.h"
 #include "ash/webui/system_extensions_internals_ui/url_constants.h"
 #include "base/system/sys_info.h"
@@ -236,10 +232,6 @@
 #include "chrome/browser/ash/printing/print_management/printing_manager.h"
 #include "chrome/browser/ash/printing/print_management/printing_manager_factory.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/browser/ash/scanning/chrome_scanning_app_delegate.h"
-#include "chrome/browser/ash/scanning/scan_service.h"
-#include "chrome/browser/ash/scanning/scan_service_factory.h"
-#include "chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h"
 #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/ash/web_applications/chrome_file_manager_ui_delegate.h"
 #include "chrome/browser/ash/web_applications/face_ml/chrome_face_ml_user_provider.h"
@@ -606,30 +598,6 @@
       base::BindRepeating(&BindEcheConnectionStatusHandler, manager));
 }
 
-void BindScanService(
-    Profile* profile,
-    mojo::PendingReceiver<ash::scanning::mojom::ScanService> pending_receiver) {
-  ash::ScanService* service =
-      ash::ScanServiceFactory::GetForBrowserContext(profile);
-  if (service)
-    service->BindInterface(std::move(pending_receiver));
-}
-
-template <>
-WebUIController* NewWebUI<ash::ScanningUI>(WebUI* web_ui, const GURL& url) {
-  Profile* profile = Profile::FromWebUI(web_ui);
-  return new ash::ScanningUI(
-      web_ui, base::BindRepeating(&BindScanService, profile),
-      std::make_unique<ash::ChromeScanningAppDelegate>(web_ui));
-}
-
-template <>
-WebUIController* NewWebUI<ash::ShimlessRMADialogUI>(WebUI* web_ui,
-                                                    const GURL& url) {
-  return new ash::ShimlessRMADialogUI(
-      web_ui, std::make_unique<ash::shimless_rma::ChromeShimlessRmaDelegate>());
-}
-
 void BindMultiDeviceSetup(
     Profile* profile,
     mojo::PendingReceiver<ash::multidevice_setup::mojom::MultiDeviceSetup>
@@ -949,12 +917,6 @@
     return &NewWebUI<ash::cellular_setup::MobileSetupUI>;
   if (url.host_piece() == ash::kChromeUIPrintManagementHost)
     return &NewWebUI<ash::printing::printing_manager::PrintManagementUI>;
-  if (url.host_piece() == ash::kChromeUIScanningAppHost)
-    return &NewWebUI<ash::ScanningUI>;
-  if (ash::shimless_rma::HasLaunchRmaSwitchAndIsAllowed() &&
-      url.host_piece() == ash::kChromeUIShimlessRMAHost) {
-    return &NewWebUI<ash::ShimlessRMADialogUI>;
-  }
   if (url.host_piece() == ash::kChromeUIMediaAppHost)
     return &NewComponentUI<ash::MediaAppUI, ChromeMediaAppUIDelegate>;
   if (url.host_piece() == ash::multidevice::kChromeUIProximityAuthHost &&
diff --git a/chrome/browser/ui/webui/chromeos/chrome_web_ui_configs_chromeos.cc b/chrome/browser/ui/webui/chromeos/chrome_web_ui_configs_chromeos.cc
index 8dc215c9..2bfe0ee 100644
--- a/chrome/browser/ui/webui/chromeos/chrome_web_ui_configs_chromeos.cc
+++ b/chrome/browser/ui/webui/chromeos/chrome_web_ui_configs_chromeos.cc
@@ -27,11 +27,15 @@
 #include "ash/webui/firmware_update_ui/firmware_update_app_ui.h"
 #include "ash/webui/guest_os_installer/guest_os_installer_ui.h"
 #include "ash/webui/os_feedback_ui/os_feedback_ui.h"
+#include "ash/webui/scanning/scanning_ui.h"
+#include "ash/webui/shimless_rma/shimless_rma.h"
 #include "ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.h"
 #include "ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.h"
 #include "chrome/browser/ash/guest_os/public/installer_delegate_factory.h"
 #include "chrome/browser/ash/net/network_health/network_health_manager.h"
 #include "chrome/browser/ash/os_feedback/chrome_os_feedback_delegate.h"
+#include "chrome/browser/ash/scanning/chrome_scanning_app_delegate.h"
+#include "chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h"
 #include "chrome/browser/ash/web_applications/camera_app/chrome_camera_app_ui_delegate.h"
 #include "chrome/browser/ash/web_applications/files_internals_ui_delegate.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h"
@@ -241,7 +245,13 @@
       std::make_unique<ash::reporting::EnterpriseReportingUIConfig>());
   map.AddWebUIConfig(std::make_unique<ash::PowerUIConfig>());
   map.AddWebUIConfig(std::make_unique<ash::RemoteMaintenanceCurtainUIConfig>());
+  map.AddWebUIConfig(
+      MakeComponentConfigWithDelegate<ash::ScanningUIConfig, ash::ScanningUI,
+                                      ash::ChromeScanningAppDelegate>());
   map.AddWebUIConfig(std::make_unique<ash::SetTimeUIConfig>());
+  map.AddWebUIConfig(MakeComponentConfigWithDelegate<
+                     ash::ShimlessRMADialogUIConfig, ash::ShimlessRMADialogUI,
+                     ash::shimless_rma::ChromeShimlessRmaDelegate>());
   map.AddWebUIConfig(std::make_unique<ash::ShortcutCustomizationAppUIConfig>());
   map.AddWebUIConfig(std::make_unique<ash::SlowTraceControllerConfig>());
   map.AddWebUIConfig(std::make_unique<ash::SlowUIConfig>());
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
index 416addc..e31f1e33 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
@@ -87,19 +87,21 @@
 
   void FlushForTesting() { receiver_.FlushForTesting(); }
 
-  MOCK_METHOD1(SetTheme, void(new_tab_page::mojom::ThemePtr));
-  MOCK_METHOD2(SetDisabledModules, void(bool, const std::vector<std::string>&));
-  MOCK_METHOD1(SetModulesFreVisibility, void(bool));
-  MOCK_METHOD1(SetCustomizeChromeSidePanelVisibility, void(bool));
-  MOCK_METHOD1(SetPromo, void(new_tab_page::mojom::PromoPtr));
+  MOCK_METHOD(void, SetTheme, (new_tab_page::mojom::ThemePtr));
+  MOCK_METHOD(void,
+              SetDisabledModules,
+              (bool, const std::vector<std::string>&));
+  MOCK_METHOD(void, SetModulesFreVisibility, (bool));
+  MOCK_METHOD(void, SetCustomizeChromeSidePanelVisibility, (bool));
+  MOCK_METHOD(void, SetPromo, (new_tab_page::mojom::PromoPtr));
 
   mojo::Receiver<new_tab_page::mojom::Page> receiver_{this};
 };
 
 class MockLogoService : public search_provider_logos::LogoService {
  public:
-  MOCK_METHOD2(GetLogo, void(search_provider_logos::LogoCallbacks, bool));
-  MOCK_METHOD1(GetLogo, void(search_provider_logos::LogoObserver*));
+  MOCK_METHOD(void, GetLogo, (search_provider_logos::LogoCallbacks, bool));
+  MOCK_METHOD(void, GetLogo, (search_provider_logos::LogoObserver*));
 };
 
 class MockColorProviderSource : public ui::ColorProviderSource {
@@ -142,9 +144,9 @@
  public:
   explicit MockNtpCustomBackgroundService(Profile* profile)
       : NtpCustomBackgroundService(profile) {}
-  MOCK_METHOD0(RefreshBackgroundIfNeeded, void());
-  MOCK_METHOD0(GetCustomBackground, absl::optional<CustomBackground>());
-  MOCK_METHOD1(AddObserver, void(NtpCustomBackgroundServiceObserver*));
+  MOCK_METHOD(void, RefreshBackgroundIfNeeded, ());
+  MOCK_METHOD(absl::optional<CustomBackground>, GetCustomBackground, ());
+  MOCK_METHOD(void, AddObserver, (NtpCustomBackgroundServiceObserver*));
 };
 
 class MockThemeService : public ThemeService {
@@ -154,7 +156,7 @@
   MOCK_CONST_METHOD0(UsingAutogeneratedTheme, bool());
   MOCK_CONST_METHOD0(UsingDefaultTheme, bool());
   MOCK_CONST_METHOD0(UsingExtensionTheme, bool());
-  MOCK_METHOD1(AddObserver, void(ThemeServiceObserver*));
+  MOCK_METHOD(void, AddObserver, (ThemeServiceObserver*));
 
  private:
   ThemeHelper theme_helper_;
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
index 68e6d4b..f3fcb23 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/check.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/files/file_path.h"
@@ -287,11 +288,10 @@
   DCHECK(!print_callback_);
   print_callback_ = std::move(callback);
 
-  PrintPreviewDialogController* dialog_controller =
-      PrintPreviewDialogController::GetInstance();
+  auto* dialog_controller = PrintPreviewDialogController::GetInstance();
+  CHECK(dialog_controller);
   content::WebContents* initiator =
-      dialog_controller ? dialog_controller->GetInitiator(preview_web_contents_)
-                        : nullptr;
+      dialog_controller->GetInitiator(preview_web_contents_);
 
   GURL initiator_url;
   bool is_savable = false;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 11750d9..30d22a9f 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -975,10 +975,8 @@
 }
 
 WebContents* PrintPreviewHandler::GetInitiator() {
-  PrintPreviewDialogController* dialog_controller =
-      PrintPreviewDialogController::GetInstance();
-  if (!dialog_controller)
-    return nullptr;
+  auto* dialog_controller = PrintPreviewDialogController::GetInstance();
+  CHECK(dialog_controller);
   return dialog_controller->GetInitiator(preview_web_contents());
 }
 
@@ -1089,10 +1087,9 @@
   // We no longer require the initiator details. Remove those details associated
   // with the preview dialog to allow the initiator to create another preview
   // dialog.
-  PrintPreviewDialogController* dialog_controller =
-      PrintPreviewDialogController::GetInstance();
-  if (dialog_controller)
-    dialog_controller->EraseInitiatorInfo(preview_web_contents());
+  auto* dialog_controller = PrintPreviewDialogController::GetInstance();
+  CHECK(dialog_controller);
+  dialog_controller->EraseInitiatorInfo(preview_web_contents());
 }
 
 PrinterHandler* PrintPreviewHandler::GetPrinterHandler(
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 641551c..e8a5af6 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/check.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/id_map.h"
 #include "base/files/file_path.h"
@@ -128,10 +129,8 @@
 }
 
 WebContents* GetInitiator(content::WebUI* web_ui) {
-  PrintPreviewDialogController* dialog_controller =
-      PrintPreviewDialogController::GetInstance();
-  if (!dialog_controller)
-    return nullptr;
+  auto* dialog_controller = PrintPreviewDialogController::GetInstance();
+  CHECK(dialog_controller);
   return dialog_controller->GetInitiator(web_ui->GetWebContents());
 }
 
diff --git a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
index 2ab0fb3..b073830 100644
--- a/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
+++ b/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
@@ -128,7 +128,7 @@
 // Verify registry updated with regular settings search tags when flag is
 // disabled.
 TEST_F(DeviceSectionTest, SearchResultChangeBackWithoutFlag) {
-  feature_list_.Reset();
+  feature_list_.InitAndDisableFeature(features::kInputDeviceSettingsSplit);
   device_section_ = std::make_unique<DeviceSection>(
       profile(), search_tag_registry(), pref_service());
 
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 9ef38794..d97099b 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -607,7 +607,7 @@
       origin_object.Set("isPartitioned", is_partitioned);
       origin_object.Set("engagement",
                         engagement_service->GetScore(origin.GetURL()));
-      origin_object.Set("usage", 0);
+      origin_object.Set("usage", 0.0);
       origin_object.Set(kNumCookies, 0);
 
       bool is_installed = installed_origins.contains(origin);
@@ -1010,7 +1010,8 @@
 
   for (const BrowsingDataModel::BrowsingDataEntryView& entry :
        *browsing_data_model_) {
-    if (*entry.primary_host != usage_hostname) {
+    auto usage_origin = url::Origin::Create(GURL(usage_origin_));
+    if (!entry.Matches(usage_origin)) {
       continue;
     }
     size += entry.data_details->storage_size;
@@ -2323,10 +2324,14 @@
     if (entry.data_details->storage_size == 0)
       continue;
 
-    // Convert the primary host to an HTTPS url to match expecations for this
-    // code.
-    url::Origin origin =
-        ConvertEtldToOrigin(*entry.primary_host, /*secure=*/true);
+    url::Origin origin = absl::visit(
+        base::Overloaded{[](const std::string& host) {
+                           // Convert the primary host to an HTTPS url to match
+                           // expecations for this code.
+                           return ConvertEtldToOrigin(host, /*secure=*/true);
+                         },
+                         [](const url::Origin& origin) { return origin; }},
+        *entry.data_owner);
     UpdateDataFromModel(all_sites_map, origin_size_map, origin,
                         entry.data_details->storage_size);
   }
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index a111a50..2a56e06fd 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -659,7 +659,8 @@
     auto mock_cookies_tree_model = std::make_unique<CookiesTreeModel>(
         std::move(container), profile()->GetExtensionSpecialStoragePolicy());
 
-    auto fake_browsing_data_model = std::make_unique<FakeBrowsingDataModel>();
+    auto fake_browsing_data_model = std::make_unique<FakeBrowsingDataModel>(
+        ChromeBrowsingDataModelDelegate::CreateForProfile(profile()));
 
     std::move(setup).Run(
         {mock_browsing_data_cookie_helper,
@@ -1559,7 +1560,7 @@
                  MakeApp(app_id, apps::AppType::kWeb, iwa_url.spec(),
                          apps::Readiness::kReady, apps::InstallReason::kUser));
 
-  SetupModels(base::DoNothing());
+  SetupModelsWithIsolatedWebAppData(iwa_url.spec(), 50);
   HostContentSettingsMap* map =
       HostContentSettingsMapFactory::GetForProfile(profile());
   map->SetContentSettingDefaultScope(iwa_url, iwa_url,
@@ -1578,6 +1579,7 @@
   EXPECT_EQ(CHECK_DEREF(group1.FindString("etldPlus1")), iwa_url);
   EXPECT_EQ(CHECK_DEREF(group1.FindString("displayName")), "IWA Name");
   EXPECT_EQ(CHECK_DEREF(origin1.FindString("origin")), iwa_url);
+  EXPECT_EQ(origin1.FindDouble("usage").value(), 50.0);
 
   const base::Value::Dict& group2 = site_groups[1].GetDict();
   const base::Value::Dict& origin2 =
@@ -1585,6 +1587,7 @@
   EXPECT_EQ(CHECK_DEREF(group2.FindString("etldPlus1")), iwa_hostname);
   EXPECT_EQ(CHECK_DEREF(group2.FindString("displayName")), iwa_hostname);
   EXPECT_EQ(CHECK_DEREF(origin2.FindString("origin")), https_url);
+  EXPECT_EQ(origin2.FindDouble("usage").value(), 0.0);
 }
 #endif  // !BUILDFLAG(IS_ANDROID)
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
index 1f5dfd8..6fe563a 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
@@ -155,11 +155,13 @@
       void(std::vector<side_panel::mojom::ModuleSettingsPtr> modules_settings,
            bool managed,
            bool visible));
-  MOCK_METHOD2(SetMostVisitedSettings,
-               void(bool custom_links_enabled, bool visible));
-  MOCK_METHOD1(SetTheme, void(side_panel::mojom::ThemePtr));
-  MOCK_METHOD1(ScrollToSection,
-               void(side_panel::mojom::CustomizeChromeSection));
+  MOCK_METHOD(void,
+              SetMostVisitedSettings,
+              (bool custom_links_enabled, bool visible));
+  MOCK_METHOD(void, SetTheme, (side_panel::mojom::ThemePtr));
+  MOCK_METHOD(void,
+              ScrollToSection,
+              (side_panel::mojom::CustomizeChromeSection));
 
   mojo::Receiver<side_panel::mojom::CustomizeChromePage> receiver_{this};
 };
@@ -168,18 +170,19 @@
  public:
   explicit MockNtpCustomBackgroundService(Profile* profile)
       : NtpCustomBackgroundService(profile) {}
-  MOCK_METHOD0(GetCustomBackground, absl::optional<CustomBackground>());
-  MOCK_METHOD0(ResetCustomBackgroundInfo, void());
-  MOCK_METHOD1(SelectLocalBackgroundImage, void(const base::FilePath&));
-  MOCK_METHOD1(AddObserver, void(NtpCustomBackgroundServiceObserver*));
-  MOCK_METHOD6(SetCustomBackgroundInfo,
-               void(const GURL&,
-                    const GURL&,
-                    const std::string&,
-                    const std::string&,
-                    const GURL&,
-                    const std::string&));
-  MOCK_METHOD0(IsCustomBackgroundDisabledByPolicy, bool());
+  MOCK_METHOD(absl::optional<CustomBackground>, GetCustomBackground, ());
+  MOCK_METHOD(void, ResetCustomBackgroundInfo, ());
+  MOCK_METHOD(void, SelectLocalBackgroundImage, (const base::FilePath&));
+  MOCK_METHOD(void, AddObserver, (NtpCustomBackgroundServiceObserver*));
+  MOCK_METHOD(void,
+              SetCustomBackgroundInfo,
+              (const GURL&,
+               const GURL&,
+               const std::string&,
+               const std::string&,
+               const GURL&,
+               const std::string&));
+  MOCK_METHOD(bool, IsCustomBackgroundDisabledByPolicy, ());
 };
 
 class MockNtpBackgroundService : public NtpBackgroundService {
@@ -189,9 +192,9 @@
       : NtpBackgroundService(url_loader_factory) {}
   MOCK_CONST_METHOD0(collection_info, std::vector<CollectionInfo>&());
   MOCK_CONST_METHOD0(collection_images, std::vector<CollectionImage>&());
-  MOCK_METHOD0(FetchCollectionInfo, void());
-  MOCK_METHOD1(FetchCollectionImageInfo, void(const std::string&));
-  MOCK_METHOD1(AddObserver, void(NtpBackgroundServiceObserver*));
+  MOCK_METHOD(void, FetchCollectionInfo, ());
+  MOCK_METHOD(void, FetchCollectionImageInfo, (const std::string&));
+  MOCK_METHOD(void, AddObserver, (NtpBackgroundServiceObserver*));
 };
 
 class MockThemeService : public ThemeService {
@@ -204,8 +207,8 @@
   MOCK_CONST_METHOD0(UsingPolicyTheme, bool());
   MOCK_CONST_METHOD0(GetAutogeneratedThemeColor, SkColor());
   MOCK_CONST_METHOD0(GetThemeID, std::string());
-  MOCK_METHOD0(UseDefaultTheme, void());
-  MOCK_METHOD1(BuildAutogeneratedThemeFromColor, void(SkColor));
+  MOCK_METHOD(void, UseDefaultTheme, ());
+  MOCK_METHOD(void, BuildAutogeneratedThemeFromColor, (SkColor));
 
  private:
   ThemeHelper theme_helper_;
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
index e20cd93..915c27e2 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
@@ -455,9 +455,9 @@
              const std::vector<std::string>& url_specs,
              base::mac::LaunchApplicationOptions options,
              base::mac::LaunchApplicationCallback callback,
-             base::expected<NSRunningApplication*, NSError*> result) {
-            if (result.has_value()) {
-              std::move(callback).Run(std::move(result));
+             NSRunningApplication* app, NSError* error) {
+            if (app) {
+              std::move(callback).Run(app, nil);
               return;
             }
 
@@ -465,15 +465,15 @@
               // In newer Mac OS versions this workaround isn't needed, and in
               // fact can itself cause flaky tests by launching the app twice
               // when only one launch is expected.
-              std::move(callback).Run(std::move(result));
+              std::move(callback).Run(app, error);
               return;
             }
 
             // Only retry for the one specific error code that seems to need
             // this. Like above, retrying in all cases can otherwise itself
             // cause flaky tests.
-            if (result.error().domain == NSCocoaErrorDomain &&
-                result.error().code == NSFileReadCorruptFileError) {
+            if (error.domain == NSCocoaErrorDomain &&
+                error.code == NSFileReadCorruptFileError) {
               LOG(ERROR) << "Failed to open application with path: "
                          << app_bundle_path << ", retrying in 100ms";
               internals::GetShortcutIOTaskRunner()->PostDelayedTask(
@@ -484,7 +484,7 @@
                   base::Milliseconds(100));
               return;
             }
-            std::move(callback).Run(std::move(result));
+            std::move(callback).Run(nil, error);
           },
           app_bundle_path, command_line, url_specs, options,
           std::move(callback)));
@@ -509,26 +509,26 @@
              base::mac::LaunchApplicationOptions options,
              const std::string& bundle_id,
              base::mac::LaunchApplicationCallback callback,
-             base::expected<NSRunningApplication*, NSError*> result) {
-            if (result.has_value()) {
-              std::move(callback).Run(std::move(result));
+             NSRunningApplication* app, NSError* error) {
+            if (app) {
+              std::move(callback).Run(app, nil);
               return;
             }
 
             LOG(ERROR) << "Failed to open application with path: "
                        << app_bundle_path;
             if (!options.create_new_instance) {
-              NSRunningApplication* app =
+              NSRunningApplication* actual_app =
                   FindRunningApplicationForBundleIdAndPath(bundle_id,
                                                            app_bundle_path);
-              if (app) {
+              if (actual_app) {
                 LOG(ERROR) << "But found a running application anyway.";
-                std::move(callback).Run(app);
+                std::move(callback).Run(actual_app, nil);
                 return;
               }
             }
 
-            std::move(callback).Run(result);
+            std::move(callback).Run(app, error);
           },
           app_bundle_path, options, bundle_id, std::move(callback)));
 }
@@ -571,10 +571,9 @@
              bool launched_after_rebuild, const std::string& bundle_id,
              ShimLaunchedCallback launched_callback,
              ShimTerminatedCallback terminated_callback,
-             base::expected<NSRunningApplication*, NSError*> result) {
-            if (result.has_value()) {
-              RunAppLaunchCallbacks(result.value(),
-                                    std::move(launched_callback),
+             NSRunningApplication* app, NSError* error) {
+            if (app) {
+              RunAppLaunchCallbacks(app, std::move(launched_callback),
                                     std::move(terminated_callback));
               return;
             }
@@ -1727,15 +1726,15 @@
           [](const base::FilePath& shim_path,
              ShimLaunchedCallback launched_callback,
              ShimTerminatedCallback terminated_callback,
-             base::expected<NSRunningApplication*, NSError*> result) {
-            if (!result.has_value()) {
+             NSRunningApplication* app, NSError* error) {
+            if (error) {
               LOG(ERROR) << "Failed to open application with path: "
                          << shim_path;
 
               std::move(launched_callback).Run(base::Process());
               return;
             }
-            RunAppLaunchCallbacks(result.value(), std::move(launched_callback),
+            RunAppLaunchCallbacks(app, std::move(launched_callback),
                                   std::move(terminated_callback));
           },
           shim_path, std::move(launched_callback),
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt
index 96c498a..810e277 100644
--- a/chrome/build/lacros-arm64.pgo.txt
+++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm64-generic-main-1683259166-7c61dc1e369be9b0d7676b0004a6d770ec9ad60c.profdata
+chrome-chromeos-arm64-generic-main-1683302258-e06017dd3f96bcc42266844de5666f21d3087169.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index d36d7cb..f203da36 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1683287395-e0834e1769241f553a24ba474946ed5dafc3b382.profdata
+chrome-chromeos-amd64-generic-main-1683302258-b7aabf02429ccadcfb377c4a6d7b99e165a07ba3.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index ec27944..babac0e8 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1683295191-ca18afdaae45dc0b73a51d3f72c4698058dc956f.profdata
+chrome-mac-arm-main-1683316719-355d7226d8c31ed2f1bba7f2bc8d0a4db8253f7c.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index f9b9d49..f769b72a 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1683287395-cc76d30794519f7954dd94c3d999422a62c59769.profdata
+chrome-win32-main-1683309585-625a379f4a97e38485dac6af215bf8db5ac8f4c1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 15f8233..6172cda 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1683298713-7bfa7e4aaa27ba3be4950f30251817c2b379832f.profdata
+chrome-win64-main-1683309585-2d865c00586cc24c43c30fcf86d6604ec5b9d792.profdata
diff --git a/chrome/services/qrcode_generator/qrcode_generator_service_impl.cc b/chrome/services/qrcode_generator/qrcode_generator_service_impl.cc
index 20d0bb22..5e4d80a 100644
--- a/chrome/services/qrcode_generator/qrcode_generator_service_impl.cc
+++ b/chrome/services/qrcode_generator/qrcode_generator_service_impl.cc
@@ -196,11 +196,10 @@
   // No locator on bottom-right.
 }
 
-void QRCodeGeneratorServiceImpl::RenderBitmap(
+SkBitmap QRCodeGeneratorServiceImpl::RenderBitmap(
     base::span<const uint8_t> data,
     const gfx::Size data_size,
-    const mojom::GenerateQRCodeRequestPtr& request,
-    mojom::GenerateQRCodeResponsePtr* response) {
+    const mojom::GenerateQRCodeRequest& request) {
   // Setup: create colors and clear canvas.
   SkBitmap bitmap;
   bitmap.allocN32Pixels(data_size.width() * kModuleSizePixels,
@@ -228,7 +227,7 @@
           continue;
         }
 
-        if (request->render_module_style == mojom::ModuleStyle::CIRCLES) {
+        if (request.render_module_style == mojom::ModuleStyle::CIRCLES) {
           float xc = (x + 0.5) * kModuleSizePixels;
           float yc = (y + 0.5) * kModuleSizePixels;
           SkScalar radius = kModuleSizePixels / 2 - 1;
@@ -244,12 +243,12 @@
   }
 
   DrawLocators(&canvas, data_size, paint_black, paint_white,
-               request->render_locator_style);
+               request.render_locator_style);
 
   SkRect bitmap_bounds;
   bitmap.getBounds(&bitmap_bounds);
 
-  switch (request->center_image) {
+  switch (request.center_image) {
     case mojom::CenterImage::DEFAULT_NONE:
       break;
     case mojom::CenterImage::CHROME_DINO:
@@ -261,7 +260,7 @@
       break;
   }
 
-  (*response)->bitmap = bitmap;
+  return bitmap;
 }
 
 void QRCodeGeneratorServiceImpl::GenerateQRCode(
@@ -318,8 +317,8 @@
 
   {
     base::TimeTicks start_time = base::TimeTicks::Now();
-    RenderBitmap(base::make_span(qr_data->data), response->data_size, request,
-                 &response);
+    response->bitmap = RenderBitmap(base::make_span(qr_data->data),
+                                    response->data_size, *request);
     base::UmaHistogramTimes(
         "Sharing.QRCodeGeneration.Duration.QrPixelsToQrImage",
         base::TimeTicks::Now() - start_time);
diff --git a/chrome/services/qrcode_generator/qrcode_generator_service_impl.h b/chrome/services/qrcode_generator/qrcode_generator_service_impl.h
index 3ce775d..6dba63e 100644
--- a/chrome/services/qrcode_generator/qrcode_generator_service_impl.h
+++ b/chrome/services/qrcode_generator/qrcode_generator_service_impl.h
@@ -66,19 +66,15 @@
                         const SkBitmap& image);
 
   // Renders the QR code with pixel information in |data| and render parameters
-  // in |request|. Result is stored into |response|.
+  // in |request|.
   // |data| is input data, one element per module, row-major.
   // |data_size| is the dimensions of |data|, in modules. Currently expected to
   //     be square, but function should cope with other shapes.
   // |request| is the mojo service request object to Generate().
   //     It includes rendering style preferences expressed by the client.
-  // |response| is the mojo service request object to Generate().
-  //     The bitmap will be populated as a response field if requested by the
-  //     client.
-  void RenderBitmap(base::span<const uint8_t> data,
-                    const gfx::Size data_size,
-                    const mojom::GenerateQRCodeRequestPtr& request,
-                    mojom::GenerateQRCodeResponsePtr* response);
+  SkBitmap RenderBitmap(base::span<const uint8_t> data,
+                        const gfx::Size data_size,
+                        const mojom::GenerateQRCodeRequest& request);
 
   mojo::Receiver<mojom::QRCodeGeneratorService> receiver_;
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 2896aa8..f477ab1b 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -9215,6 +9215,8 @@
       "../browser/supervised_user/supervised_user_google_auth_navigation_throttle_unittest.cc",
       "../browser/supervised_user/supervised_user_service_unittest.cc",
     ]
+    deps += [ "//components/supervised_user/core/browser:fetcher" ]
+
     if (is_chromeos) {
       sources += [
         "../browser/supervised_user/chromeos/mock_large_icon_service.cc",
diff --git a/chrome/test/data/extensions/blocked_actions/content_script_at_end/manifest.json b/chrome/test/data/extensions/blocked_actions/content_script_at_end/manifest.json
new file mode 100644
index 0000000..b29779940
--- /dev/null
+++ b/chrome/test/data/extensions/blocked_actions/content_script_at_end/manifest.json
@@ -0,0 +1,11 @@
+{
+  "name": "Blocked Actions Doc End",
+  "description": "An extension that wants to run at document end on all urls.",
+  "version": "0.1",
+  "manifest_version": 3,
+  "content_scripts": [{
+    "matches": ["<all_urls>"],
+    "run_at": "document_end",
+    "js": ["script.js"]
+  }]
+}
diff --git a/chrome/test/data/extensions/blocked_actions/content_script_at_end/script.js b/chrome/test/data/extensions/blocked_actions/content_script_at_end/script.js
new file mode 100644
index 0000000..eb157dc
--- /dev/null
+++ b/chrome/test/data/extensions/blocked_actions/content_script_at_end/script.js
@@ -0,0 +1,10 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Set the title of the document to the success state (so that it's easily
+// readable from the C++ side).
+document.title = 'success';
+
+// Send a succeeded injection message that we can wait for in the test.
+chrome.test.sendMessage("injection succeeded");
diff --git a/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/background.js b/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/background.js
new file mode 100644
index 0000000..eca0231a
--- /dev/null
+++ b/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/background.js
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function changeDocumentTitle() {
+  document.title = 'success';
+  chrome.test.sendMessage("injection succeeded");
+}
+
+chrome.webNavigation.onCommitted.addListener(async function(activeInfo) {
+  let tab = await getCurrentTab();
+  await chrome.scripting.executeScript({
+    target: { tabId: tab.id },
+    function: changeDocumentTitle
+  });
+});
+
+async function getCurrentTab() {
+  let queryOptions = { active: true, currentWindow: true};
+  let [tab] = await chrome.tabs.query(queryOptions);
+  return tab;
+}
diff --git a/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/manifest.json b/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/manifest.json
new file mode 100644
index 0000000..b64b7b39
--- /dev/null
+++ b/chrome/test/data/extensions/blocked_actions/revoke_execute_script_on_click/manifest.json
@@ -0,0 +1,17 @@
+{
+  "name": "Blocked Actions Change Title all urls",
+  "action": {},
+  "manifest_version": 3,
+  "version": "0.1",
+  "permissions": [
+    "scripting",
+    "webNavigation",
+    "tabs"
+  ],
+  "host_permissions": [
+    "<all_urls>"
+  ],
+  "background": {
+    "service_worker": "background.js"
+  }
+}
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
index 9584c28..42b50a4 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
@@ -63,6 +63,14 @@
   return document.querySelector('personalization-router');
 }
 
+/** Returns an array of three numbers, representing the RGB values. */
+function getBodyColorChannels() {
+  return getComputedStyle(document.body)
+      .backgroundColor.match(/rgb\((\d+), (\d+), (\d+)\)/)
+      .slice(1, 4)
+      .map(x => parseInt(x, 10));
+}
+
 class PersonalizationAppBrowserTest extends testing.Test {
   /** @override */
   get browsePreload() {
@@ -127,13 +135,45 @@
       const theme = getRouter()
                         .shadowRoot.querySelector('personalization-main')
                         .shadowRoot.querySelector('personalization-theme');
+
       const lightButton = await waitUntil(
           () => theme.shadowRoot.getElementById('lightMode'),
           'failed to find light button');
-      assertEquals('true', lightButton.getAttribute('aria-pressed'));
+      assertEquals('false', lightButton.getAttribute('aria-pressed'));
       const darkButton = theme.shadowRoot.getElementById('darkMode');
       assertTrue(!!darkButton);
-      assertEquals(darkButton.getAttribute('aria-pressed'), 'false');
+      assertEquals('false', darkButton.getAttribute('aria-pressed'));
+      const autoButton = theme.shadowRoot.getElementById('autoMode');
+      assertTrue(!!autoButton);
+      assertEquals('true', autoButton.getAttribute('aria-pressed'));
+    });
+
+    test('selects dark mode', async () => {
+      const theme = getRouter()
+                        .shadowRoot.querySelector('personalization-main')
+                        .shadowRoot.querySelector('personalization-theme');
+      const darkButton = theme.shadowRoot.getElementById('darkMode');
+
+      darkButton.click();
+
+      assertEquals('true', darkButton.getAttribute('aria-pressed'));
+      await waitUntil(
+          () => getBodyColorChannels().every(channel => channel < 50),
+          'failed to switch to dark mode');
+    });
+
+    test('selects light mode', async () => {
+      const theme = getRouter()
+                        .shadowRoot.querySelector('personalization-main')
+                        .shadowRoot.querySelector('personalization-theme');
+      const lightButton = theme.shadowRoot.getElementById('lightMode');
+
+      lightButton.click();
+
+      assertEquals('true', lightButton.getAttribute('aria-pressed'));
+      await waitUntil(
+          () => getBodyColorChannels().every(channel => channel > 200),
+          'failed to switch to light mode');
     });
 
     test('shows user info', async () => {
diff --git a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts
index b0e9c377..ce2dd57 100644
--- a/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts
+++ b/chrome/test/data/webui/new_tab_page/modules/history_clusters/module_test.ts
@@ -8,7 +8,8 @@
 import {Cluster, URLVisit} from 'chrome://new-tab-page/history_cluster_types.mojom-webui.js';
 import {PageHandlerRemote} from 'chrome://new-tab-page/history_clusters.mojom-webui.js';
 import {DismissModuleEvent, HistoryClusterElementType, HistoryClusterImageDisplayState, HistoryClusterLayoutType, historyClustersDescriptor, HistoryClustersModuleElement, HistoryClustersProxyImpl, LAYOUT_1_MIN_IMAGE_VISITS, LAYOUT_1_MIN_VISITS, LAYOUT_2_MIN_IMAGE_VISITS, LAYOUT_2_MIN_VISITS, LAYOUT_3_MIN_IMAGE_VISITS, LAYOUT_3_MIN_VISITS, PageImageServiceBrowserProxy} from 'chrome://new-tab-page/lazy_load.js';
-import {$$} from 'chrome://new-tab-page/new_tab_page.js';
+import {$$, NewTabPageProxy} from 'chrome://new-tab-page/new_tab_page.js';
+import {PageRemote} from 'chrome://new-tab-page/new_tab_page.mojom-webui.js';
 import {PageImageServiceHandlerRemote} from 'chrome://resources/cr_components/page_image_service/page_image_service.mojom-webui.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -69,6 +70,7 @@
   let handler: TestMock<PageHandlerRemote>;
   let imageServiceHandler: TestMock<PageImageServiceHandlerRemote>;
   let metrics: MetricsTracker;
+  let newTabPageCallbackRouterRemote: PageRemote;
 
   setup(() => {
     document.body.innerHTML = window.trustedTypes!.emptyHTML;
@@ -81,6 +83,9 @@
         mock => PageImageServiceBrowserProxy.setInstance(
             new PageImageServiceBrowserProxy(mock)));
     metrics = fakeMetricsPrivate();
+    newTabPageCallbackRouterRemote =
+        NewTabPageProxy.getInstance()
+            .callbackRouter.$.bindNewPipeAndPassRemote();
   });
 
   async function initializeModule(clusters: Cluster[], cart: Cart|null = null):
@@ -443,5 +448,57 @@
       assertTrue(!!cartTile);
       assertTrue(!!moduleElement.cart);
     });
+
+    test('Cart tile controlled by settings', async () => {
+      loadTimeData.overrideValues({
+        modulesChromeCartInHistoryClustersModuleEnabled: true,
+      });
+
+      // Arrange.
+      const cart: Cart = Object.assign({
+        domain: 'foo.com',
+        merchant: 'Foo',
+        cartUrl: {url: 'https://foo.com'},
+        productImageUrls: [],
+        discountText: '',
+        relativeDate: '6 mins ago',
+      });
+      const moduleElement = await initializeModule(
+          [createSampleCluster(HistoryClusterLayoutType.LAYOUT_1)], cart);
+
+      assertEquals(1, handler.getCallCount('getCartForCluster'));
+      assertTrue(!!moduleElement);
+      await waitAfterNextRender(moduleElement);
+      let cartTile = moduleElement.shadowRoot!.getElementById('cartTile');
+      let questTiles = moduleElement.shadowRoot!.querySelectorAll(
+          'ntp-history-clusters-tile');
+      assertTrue(!!cartTile);
+      assertTrue(!!moduleElement.cart);
+      assertEquals(1, questTiles.length);
+
+      // Act.
+      newTabPageCallbackRouterRemote.setDisabledModules(false, ['chrome_cart']);
+      await waitAfterNextRender(moduleElement);
+
+      // Assert.
+      cartTile = moduleElement.shadowRoot!.getElementById('cartTile');
+      questTiles = moduleElement.shadowRoot!.querySelectorAll(
+          'ntp-history-clusters-tile');
+      assertTrue(!cartTile);
+      assertTrue(!moduleElement.cart);
+      assertEquals(2, questTiles.length);
+
+      // Act.
+      newTabPageCallbackRouterRemote.setDisabledModules(false, []);
+      await waitAfterNextRender(moduleElement);
+
+      // Assert.
+      cartTile = moduleElement.shadowRoot!.getElementById('cartTile');
+      questTiles = moduleElement.shadowRoot!.querySelectorAll(
+          'ntp-history-clusters-tile');
+      assertTrue(!!cartTile);
+      assertTrue(!!moduleElement.cart);
+      assertEquals(1, questTiles.length);
+    });
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index 9e2db367..155639d 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -61,7 +61,6 @@
     "internet_subpage_menu_test.js",
     "lock_screen_subpage_test.ts",
     "manage_users_subpage_tests.js",
-    "multidevice_feature_item_tests.js",
     "multidevice_feature_toggle_tests.js",
     "nearby_share_receive_dialog_tests.js",
     "nearby_share_subpage_tests.js",
@@ -181,6 +180,7 @@
 
     "multidevice_page/multidevice_page_tests.js",
     "multidevice_page/multidevice_combined_setup_item_test.ts",
+    "multidevice_page/multidevice_feature_item_test.ts",
     "multidevice_page/multidevice_notification_access_setup_dialog_tests.js",
     "multidevice_page/multidevice_permissions_setup_dialog_tests.js",
     "multidevice_page/multidevice_smartlock_item_test.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.js
index 7877581f..1bc92f1c 100644
--- a/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.js
@@ -205,19 +205,6 @@
     }
   });
 
-  // Verify the printer status icons are only visible for saved printers.
-  test('savedPrinterShowPrinterStatusIcons', function() {
-    printerEntryTestElement.printerEntry =
-        createPrinterEntry(PrinterType.SAVED);
-    assertTrue(isVisible(printerEntryTestElement.shadowRoot.querySelector(
-        '#printerStatusIcon')));
-
-    printerEntryTestElement.printerEntry =
-        createPrinterEntry(PrinterType.AUTOMATIC);
-    assertFalse(isVisible(printerEntryTestElement.shadowRoot.querySelector(
-        '#printerStatusIcon')));
-  });
-
   // Verify the correct printer status icon is shown based on the printer's
   // status reason.
   test('savedPrinterCorrectPrinterStatusIcon', function() {
@@ -248,4 +235,27 @@
         printerEntryTestElement.shadowRoot.querySelector('#printerStatusIcon')
             .icon);
   });
+
+  // Verify the printer icon is visible based on the printer's type.
+  test('visiblePrinterIconByPrinterType', function() {
+    printerEntryTestElement.printerEntry =
+        createPrinterEntry(PrinterType.ENTERPRISE);
+    assertFalse(isVisible(printerEntryTestElement.shadowRoot.querySelector(
+        '#printerStatusIcon')));
+
+    printerEntryTestElement.printerEntry =
+        createPrinterEntry(PrinterType.DISCOVERED);
+    assertTrue(isVisible(printerEntryTestElement.shadowRoot.querySelector(
+        '#printerStatusIcon')));
+
+    printerEntryTestElement.printerEntry =
+        createPrinterEntry(PrinterType.AUTOMATIC);
+    assertTrue(isVisible(printerEntryTestElement.shadowRoot.querySelector(
+        '#printerStatusIcon')));
+
+    printerEntryTestElement.printerEntry =
+        createPrinterEntry(PrinterType.SAVED);
+    assertTrue(isVisible(printerEntryTestElement.shadowRoot.querySelector(
+        '#printerStatusIcon')));
+  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js
index e4f96fef..020fd28 100644
--- a/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {CupsPrintersBrowserProxyImpl, PrinterType} from 'chrome://os-settings/chromeos/lazy_load.js';
+import {CupsPrintersBrowserProxyImpl, PrinterStatusReason, PrinterStatusSeverity, PrinterType} from 'chrome://os-settings/chromeos/lazy_load.js';
 import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
-import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
 import {webUIListenerCallback} from 'chrome://resources/ash/common/cr.m.js';
+import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
 import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js';
 import {NetworkStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
 import {ConnectionStateType, NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertNotReached} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
 
 import {createCupsPrinterInfo, createPrinterListEntry, getPrinterEntries} from './cups_printer_test_utils.js';
@@ -654,6 +655,51 @@
         'First saved printer menu button should be focused for settingId=1401.');
   });
 
+  test('SavedPrintersStatusUpdates', async () => {
+    createCupsPrinterPage([
+      createCupsPrinterInfo('test1', '1', 'id1'),
+      createCupsPrinterInfo('test2', '2', 'id2'),
+      createCupsPrinterInfo('test3', '3', 'id3'),
+    ]);
+
+    cupsPrintersBrowserProxy.addPrinterStatus(
+        'id1', PrinterStatusReason.NO_ERROR, PrinterStatusSeverity.ERROR);
+    cupsPrintersBrowserProxy.addPrinterStatus(
+        'id2', PrinterStatusReason.PRINTER_UNREACHABLE,
+        PrinterStatusSeverity.ERROR);
+
+    await cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList');
+    await flushTasks();
+
+    savedPrintersElement =
+        page.shadowRoot.querySelector('settings-cups-saved-printers');
+    assertTrue(!!savedPrintersElement);
+
+    // For each of the 3 saved printers verify it gets the correct printer
+    // status reason based on the printer status previously set.
+    const printerListEntries = getPrinterEntries(savedPrintersElement);
+    assertEquals(3, printerListEntries.length);
+    for (const entry of printerListEntries) {
+      let expectedPrinterStatusReason;
+      const printerInfo = entry.printerEntry.printerInfo;
+      switch (printerInfo.printerId) {
+        case 'id1':
+          expectedPrinterStatusReason = PrinterStatusReason.NO_ERROR;
+          break;
+        case 'id2':
+          expectedPrinterStatusReason = PrinterStatusReason.PRINTER_UNREACHABLE;
+          break;
+        case 'id3':
+          expectedPrinterStatusReason = PrinterStatusReason.UNKNOWN_REASON;
+          break;
+        default:
+          assertNotReached();
+      }
+      assertEquals(
+          expectedPrinterStatusReason, printerInfo.printerStatusReason);
+    }
+  });
+
   test('ShowMoreButtonIsInitiallyHiddenAndANewPrinterIsAdded', function() {
     createCupsPrinterPage([
       createCupsPrinterInfo('google', '4', 'id4'),
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_feature_item_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_feature_item_tests.js
deleted file mode 100644
index f8688a1..0000000
--- a/chrome/test/data/webui/settings/chromeos/multidevice_feature_item_tests.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {MultiDeviceFeature, MultiDeviceFeatureState, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {eventToPromise} from 'chrome://webui-test/test_util.js';
-
-import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
-
-suite('Multidevice', function() {
-  /** @type {?SettingsMultideviceFeatureItemElement} */
-  let featureItem = null;
-  /** @type {?SettingsMultideviceFeatureToggleElement} */
-  let featureToggle = null;
-  /** @type {?CrToggleElement} */
-  let crToggle = null;
-  /** @type {?MultiDeviceFeatureState} */
-  let featureState = null;
-
-  /** @type {!Route} */
-  let initialRoute;
-
-  // Fake MultiDeviceFeature enum value
-  const FAKE_MULTIDEVICE_FEATURE = -1;
-  const FAKE_SUMMARY_HTML = 'Gives you candy <a href="link">Learn more.</a>';
-
-  /** Resets both the suite and the (fake) feature to on state. */
-  function resetFeatureData() {
-    featureState = MultiDeviceFeatureState.ENABLED_BY_USER;
-    featureItem.pageContentData = {
-      betterTogetherState: MultiDeviceFeatureState.ENABLED_BY_USER,
-    };
-    flush();
-    assertFalse(crToggle.disabled);
-    assertTrue(crToggle.checked);
-  }
-
-  /**
-   * Clicks an element, asserts whether the click navigated the page away to a
-   * new route, then navigates back to initialRoute.
-   * @param {HTMLElement} element. Target of click.
-   * @param {boolean} shouldRouteAway. Whether the page is expected to navigate
-   * to a new route.
-   */
-  function checkWhetherClickRoutesAway(element, shouldRouteAway) {
-    element.click();
-    flush();
-    assertEquals(
-        shouldRouteAway, initialRoute !== Router.getInstance().currentRoute);
-    Router.getInstance().navigateTo(initialRoute);
-    assertEquals(initialRoute, Router.getInstance().currentRoute);
-  }
-
-  setup(function() {
-    PolymerTest.clearBody();
-
-    featureItem = document.createElement('settings-multidevice-feature-item');
-    featureItem.getFeatureSummaryHtml = () => FAKE_SUMMARY_HTML;
-    featureItem.feature = FAKE_MULTIDEVICE_FEATURE;
-    featureItem.pageContentData = {};
-    document.body.appendChild(featureItem);
-    flush();
-
-    featureToggle = featureItem.shadowRoot.querySelector(
-        'settings-multidevice-feature-toggle');
-    featureToggle.getFeatureState = () => featureState;
-
-    crToggle = featureToggle.$.toggle;
-
-    initialRoute = routes.MULTIDEVICE_FEATURES;
-    routes.FREE_CANDY = routes.BASIC.createSection('/freeCandy');
-    featureItem.subpageRoute = routes.FREE_CANDY;
-
-    resetFeatureData();
-    Router.getInstance().navigateTo(initialRoute);
-    flush();
-  });
-
-  teardown(function() {
-    featureItem.remove();
-  });
-
-  test('generic click navigates to subpage', function() {
-    checkWhetherClickRoutesAway(
-        featureItem.shadowRoot.querySelector('#item-text-container'), true);
-    checkWhetherClickRoutesAway(
-        featureItem.shadowRoot.querySelector('iron-icon'), true);
-    checkWhetherClickRoutesAway(
-        featureItem.shadowRoot.querySelector('#featureSecondary'), true);
-  });
-
-  test('link click does not navigate to subpage', function() {
-    const link = featureItem.shadowRoot.querySelector('#featureSecondary')
-                     .$.container.querySelector('a');
-    assertTrue(!!link);
-    checkWhetherClickRoutesAway(link, false);
-  });
-
-  test('row is clickable', async () => {
-    featureItem.feature = MultiDeviceFeature.BETTER_TOGETHER_SUITE;
-    featureState = MultiDeviceFeatureState.ENABLED_BY_USER;
-    featureItem.subpageRoute = null;
-    flush();
-
-    const expectedEvent =
-        eventToPromise('feature-toggle-clicked', featureToggle);
-    featureItem.shadowRoot.querySelector('#linkWrapper').click();
-    await expectedEvent;
-  });
-
-  test('toggle click does not navigate to subpage in any state', function() {
-    checkWhetherClickRoutesAway(featureToggle, false);
-
-    crToggle.checked = true;
-    assertFalse(crToggle.disabled);
-    checkWhetherClickRoutesAway(crToggle, false);
-
-    crToggle.checked = false;
-    assertFalse(crToggle.disabled);
-    checkWhetherClickRoutesAway(crToggle, false);
-  });
-});
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_feature_item_test.ts b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_feature_item_test.ts
new file mode 100644
index 0000000..bba8739b
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_feature_item_test.ts
@@ -0,0 +1,158 @@
+// Copyright 2018 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://os-settings/chromeos/lazy_load.js';
+
+import {SettingsMultideviceFeatureItemElement, SettingsMultideviceFeatureToggleElement} from 'chrome://os-settings/chromeos/lazy_load.js';
+import {CrToggleElement, LocalizedLinkElement, MultiDeviceFeature, MultiDeviceFeatureState, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason, PhoneHubFeatureAccessStatus, Route, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
+import {IronIconElement} from 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+
+suite('<settings-multidevice-feature-item>', () => {
+  let featureItem: SettingsMultideviceFeatureItemElement;
+  let featureToggle: SettingsMultideviceFeatureToggleElement;
+  let crToggle: CrToggleElement;
+  let featureState: MultiDeviceFeatureState;
+  let initialRoute: Route;
+
+  // Fake MultiDeviceFeature enum value
+  const FAKE_SUMMARY_HTML = 'Gives you candy <a href="#">Learn more.</a>';
+
+  /** Resets both the suite and the (fake) feature to on state. */
+  function resetFeatureData() {
+    featureState = MultiDeviceFeatureState.ENABLED_BY_USER;
+    featureItem.pageContentData = {
+      betterTogetherState: MultiDeviceFeatureState.ENABLED_BY_USER,
+      mode: MultiDeviceSettingsMode.NO_HOST_SET,
+      hostDeviceName: undefined,
+      instantTetheringState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      messagesState: MultiDeviceFeatureState.ENABLED_BY_USER,
+      smartLockState: MultiDeviceFeatureState.ENABLED_BY_USER,
+      phoneHubState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      phoneHubCameraRollState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      phoneHubNotificationsState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      phoneHubTaskContinuationState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      phoneHubAppsState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      wifiSyncState: MultiDeviceFeatureState.DISABLED_BY_USER,
+      isAndroidSmsPairingComplete: true,
+      cameraRollAccessStatus:
+          PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED,
+      notificationAccessStatus: PhoneHubFeatureAccessStatus.ACCESS_GRANTED,
+      appsAccessStatus: PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED,
+      notificationAccessProhibitedReason:
+          PhoneHubFeatureAccessProhibitedReason.UNKNOWN,
+      isNearbyShareDisallowedByPolicy: false,
+      isPhoneHubPermissionsDialogSupported: false,
+      isCameraRollFilePermissionGranted: false,
+      isPhoneHubFeatureCombinedSetupSupported: false,
+      isChromeOSSyncedSessionSharingEnabled: false,
+      isLacrosTabSyncEnabled: false,
+    };
+    flush();
+    assertFalse(crToggle.disabled);
+    assertTrue(crToggle.checked);
+  }
+
+  /**
+   * Clicks an element, asserts whether the click navigated the page away to a
+   * new route, then navigates back to initialRoute.
+   * @param element. Target of click.
+   * @param shouldRouteAway. Whether the page is expected to navigate
+   * to a new route.
+   */
+  function checkWhetherClickRoutesAway(
+      element: HTMLElement, shouldRouteAway: boolean) {
+    element.click();
+    flush();
+    assertEquals(
+        shouldRouteAway, initialRoute !== Router.getInstance().currentRoute);
+    Router.getInstance().navigateTo(initialRoute);
+    assertEquals(initialRoute, Router.getInstance().currentRoute);
+  }
+
+  setup(() => {
+    featureItem = document.createElement('settings-multidevice-feature-item');
+    featureItem.getFeatureSummaryHtml = () => FAKE_SUMMARY_HTML;
+    featureItem.feature = MultiDeviceFeature.BETTER_TOGETHER_SUITE;
+    document.body.appendChild(featureItem);
+    flush();
+
+    const toggle = featureItem.shadowRoot!.querySelector(
+        'settings-multidevice-feature-toggle');
+    assertTrue(!!toggle);
+    featureToggle = toggle;
+    featureToggle.getFeatureState = () => featureState;
+
+    crToggle = featureToggle.$.toggle;
+
+    initialRoute = routes.MULTIDEVICE_FEATURES;
+    const FREE_CANDY = routes.BASIC.createSection('/freeCandy', 'freeCandy');
+    featureItem.subpageRoute = FREE_CANDY;
+
+    resetFeatureData();
+    Router.getInstance().navigateTo(initialRoute);
+    flush();
+  });
+
+  teardown(() => {
+    featureItem.remove();
+  });
+
+  test('generic click navigates to subpage', () => {
+    const itemTextContainer =
+        featureItem.shadowRoot!.querySelector<HTMLElement>(
+            '#item-text-container');
+    assertTrue(!!itemTextContainer);
+    checkWhetherClickRoutesAway(itemTextContainer, true);
+    const ironIcon =
+        featureItem.shadowRoot!.querySelector<IronIconElement>('iron-icon');
+    assertTrue(!!ironIcon);
+    checkWhetherClickRoutesAway(ironIcon, true);
+    const featureSecondary =
+        featureItem.shadowRoot!.querySelector<LocalizedLinkElement>(
+            '#featureSecondary');
+    assertTrue(!!featureSecondary);
+    checkWhetherClickRoutesAway(featureSecondary, true);
+  });
+
+  test('link click does not navigate to subpage', () => {
+    const featureSecondary =
+        featureItem.shadowRoot!.querySelector<LocalizedLinkElement>(
+            '#featureSecondary');
+    assertTrue(!!featureSecondary);
+    const link = featureSecondary.$.container.querySelector('a');
+    assertTrue(!!link);
+    checkWhetherClickRoutesAway(link, false);
+  });
+
+  test('row is clickable', async () => {
+    featureItem.feature = MultiDeviceFeature.BETTER_TOGETHER_SUITE;
+    featureState = MultiDeviceFeatureState.ENABLED_BY_USER;
+    featureItem.subpageRoute = undefined;
+    flush();
+
+    const expectedEvent =
+        eventToPromise('feature-toggle-clicked', featureToggle);
+    const linkWrapper =
+        featureItem.shadowRoot!.querySelector<HTMLAnchorElement>(
+            '#linkWrapper');
+    assertTrue(!!linkWrapper);
+    linkWrapper.click();
+    await expectedEvent;
+  });
+
+  test('toggle click does not navigate to subpage in any state', () => {
+    checkWhetherClickRoutesAway(featureToggle, false);
+
+    crToggle.checked = true;
+    assertFalse(crToggle.disabled);
+    checkWhetherClickRoutesAway(crToggle, false);
+
+    crToggle.checked = false;
+    assertFalse(crToggle.disabled);
+    checkWhetherClickRoutesAway(crToggle, false);
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/os_people_page_test.js b/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
index ebdfa3a..fd4a8d0 100644
--- a/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_people_page_test.js
@@ -5,7 +5,7 @@
 import 'chrome://os-settings/chromeos/os_settings.js';
 
 import {AccountManagerBrowserProxyImpl} from 'chrome://os-settings/chromeos/lazy_load.js';
-import {osPageVisibility, PageStatus, ProfileInfoBrowserProxyImpl, Router, routes, SyncBrowserProxyImpl} from 'chrome://os-settings/chromeos/os_settings.js';
+import {osPageAvailability, PageStatus, ProfileInfoBrowserProxyImpl, Router, routes, SyncBrowserProxyImpl} from 'chrome://os-settings/chromeos/os_settings.js';
 import {assert} from 'chrome://resources/ash/common/assert.js';
 import {webUIListenerCallback} from 'chrome://resources/ash/common/cr.m.js';
 import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js';
@@ -116,7 +116,7 @@
       isAccountManagerEnabled: false,
     });
     peoplePage = document.createElement('os-settings-people-page');
-    peoplePage.pageVisibility = osPageVisibility;
+    peoplePage.pageAvailability = osPageAvailability;
     document.body.appendChild(peoplePage);
 
     await browserProxy.whenCalled('getProfileInfo');
@@ -251,7 +251,7 @@
       osProfileName: fakeOsProfileName,
     });
     peoplePage = document.createElement('os-settings-people-page');
-    peoplePage.pageVisibility = osPageVisibility;
+    peoplePage.pageAvailability = osPageAvailability;
     document.body.appendChild(peoplePage);
 
     await accountManagerBrowserProxy.whenCalled('getAccounts');
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index 385b69de..57c914a 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -248,7 +248,10 @@
      ]
    }
  ],
- ['CupsPrinterLandingPage', 'cups_printer_landing_page_tests.js'],
+ [
+   'CupsPrinterLandingPage', 'cups_printer_landing_page_tests.js',
+   {enabled: ['ash::features::kPrinterSettingsPrinterStatus']}
+ ],
  [
    'CupsPrinterPage', 'cups_printer_page_tests.js',
    {enabled: ['ash::features::kPrinterSettingsRevamp']}
@@ -386,8 +389,13 @@
  // TODO(b/208932892): Re-enable once flakiness is fixed.
  // ['MultideviceFeatureItem', 'multidevice_feature_item_tests.js'],
  ['MultideviceFeatureToggle', 'multidevice_feature_toggle_tests.js'],
+
  ['MultidevicePage', 'multidevice_page/multidevice_page_tests.js'],
  [
+   'MultidevicePageMultideviceFeatureItem',
+   'multidevice_page/multidevice_feature_item_test.js'
+ ],
+ [
    'MultidevicePageMultideviceNotificationAccessSetupDialog',
    'multidevice_page/multidevice_notification_access_setup_dialog_tests.js',
  ],
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_main_test.js b/chrome/test/data/webui/settings/chromeos/os_settings_main_test.js
index 9525875..31a58d49 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_main_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_main_test.js
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {CrSettingsPrefs, osPageVisibility, Router, routes, setContactManagerForTesting, setNearbyShareSettingsForTesting} from 'chrome://os-settings/chromeos/os_settings.js';
+import {CrSettingsPrefs, osPageAvailability, Router, routes, setContactManagerForTesting, setNearbyShareSettingsForTesting} from 'chrome://os-settings/chromeos/os_settings.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {FakeContactManager} from 'chrome://webui-test/nearby_share/shared/fake_nearby_contact_manager.js';
 import {FakeNearbyShareSettings} from 'chrome://webui-test/nearby_share/shared/fake_nearby_share_settings.js';
@@ -37,7 +36,7 @@
     settingsMain = document.createElement('os-settings-main');
     settingsMain.prefs = settingsPrefs.prefs;
     settingsMain.toolbarSpinnerActive = false;
-    settingsMain.pageVisibility = osPageVisibility;
+    settingsMain.pageAvailability = osPageAvailability;
     document.body.appendChild(settingsMain);
   });
 
@@ -102,7 +101,7 @@
    * @param {string} Expected 'display' value for the basic page.
    * @param {string} Expected 'display' value for the advanced page.
    */
-  async function assertPageVisibility(expectedBasic, expectedAdvanced) {
+  async function assertPageDisplay(expectedBasic, expectedAdvanced) {
     flush();
     const page = settingsMain.shadowRoot.querySelector('os-settings-page');
     assertEquals(
@@ -123,7 +122,7 @@
     Router.getInstance().navigateTo(routes.DEVICE);
     flush();
 
-    await assertPageVisibility('block', 'block');
+    await assertPageDisplay('block', 'block');
   });
 
   test('updates the title based on current route', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_menu_test.js b/chrome/test/data/webui/settings/chromeos/os_settings_menu_test.js
index b0e28b1..d3aabc1f 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_menu_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_menu_test.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {osPageVisibility, Route, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
+import {osPageAvailability, Route, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 /** @fileoverview Runs tests for the OS settings menu. */
@@ -32,7 +32,7 @@
     setupRouter();
     PolymerTest.clearBody();
     settingsMenu = document.createElement('os-settings-menu');
-    settingsMenu.pageVisibility = osPageVisibility;
+    settingsMenu.pageAvailability = osPageAvailability;
     document.body.appendChild(settingsMenu);
   });
 
diff --git a/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.js
index 6efce2e3..c72e6f92 100644
--- a/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.js
+++ b/chrome/test/data/webui/settings/chromeos/test_cups_printers_browser_proxy.js
@@ -25,6 +25,7 @@
       'removeCupsPrinter',
       'reconfigureCupsPrinter',
       'getEulaUrl',
+      'requestPrinterStatusUpdate',
     ]);
 
     this.printerList = /** @type{?CupsPrintersList} */ ({printerList: []});
@@ -37,6 +38,7 @@
     this.printerInfo = {};
     this.printerPpdMakeModel =
         /** @type{PrinterPpdMakeModel */ ({ppdManufacturer: '', ppdModel: ''});
+    this.printerStatusMap = {};
 
     /**
      * |eulaUrl_| in conjunction with |setEulaUrl| mimics setting the EULA url
@@ -167,6 +169,11 @@
     return Promise.resolve(this.printServerPrinters);
   }
 
+  /** @override */
+  requestPrinterStatusUpdate(printerId) {
+    this.methodCalled('requestPrinterStatusUpdate', printerId);
+    return Promise.resolve(this.printerStatusMap[printerId]);
+  }
 
   /** @param {string} eulaUrl */
   setEulaUrl(eulaUrl) {
@@ -187,4 +194,22 @@
   setAddDiscoveredPrinterFailure(printer) {
     this.addDiscoveredFailedPrinter_ = printer;
   }
+
+  /**
+   * @param {string} printerId
+   * @param {!PrinterStatusReason} reason
+   * @param {!PrinterStatusSeverity} severity
+   */
+  addPrinterStatus(printerId, reason, severity) {
+    this.printerStatusMap[printerId] = {
+      printerId: printerId,
+      statusReasons: [
+        {
+          reason: reason,
+          severity: severity,
+        },
+      ],
+      timestamp: 0,
+    };
+  }
 }
diff --git a/chrome/test/media_router/BUILD.gn b/chrome/test/media_router/BUILD.gn
index b2c0753..f654a438 100644
--- a/chrome/test/media_router/BUILD.gn
+++ b/chrome/test/media_router/BUILD.gn
@@ -57,7 +57,10 @@
     "//ui/views:test_support",
     "//url",
   ]
-  data_deps = [ ":browser_test_resources" ]
+  data_deps = [
+    ":browser_test_resources",
+    ":e2e_test_resources",
+  ]
 }
 
 copy("browser_test_resources") {
@@ -99,8 +102,8 @@
 copy("e2e_test_resources") {
   testonly = true
   sources = [
-    "../../../media/test/data/bear-vp9.webm",
-    "../../../media/test/data/player.html",
+    "//media/test/data/bear-vp9.webm",
+    "//media/test/data/player.html",
   ]
   outputs = [
     "$root_out_dir/media_router/browser_test_resources/{{source_file_part}}",
diff --git a/chrome/test/media_router/media_router_e2e_browsertest.cc b/chrome/test/media_router/media_router_e2e_browsertest.cc
index 447fb97..fc9b9f1 100644
--- a/chrome/test/media_router/media_router_e2e_browsertest.cc
+++ b/chrome/test/media_router/media_router_e2e_browsertest.cc
@@ -31,7 +31,6 @@
     "cast:BE6E4473?clientId=143692175507258981";
 const char kVideo[] = "video";
 const char kBearVP9Video[] = "bear-vp9.webm";
-const char kPlayer[] = "player.html";
 const char kOrigin[] = "http://origin/";
 }  // namespace
 
@@ -121,8 +120,8 @@
   base::StringPairs query_params;
   query_params.push_back(std::make_pair(kVideo, kBearVP9Video));
   std::string query = media::GetURLQueryString(query_params);
-  GURL gurl =
-      content::GetFileUrlWithQuery(media::GetTestDataFilePath(kPlayer), query);
+  GURL gurl = content::GetFileUrlWithQuery(
+      GetResourceFile(FILE_PATH_LITERAL("player.html")), query);
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), gurl, 1);
 }
 
diff --git a/chrome/test/media_router/media_router_integration_browsertest.h b/chrome/test/media_router/media_router_integration_browsertest.h
index 8c93d53..445a6ea 100644
--- a/chrome/test/media_router/media_router_integration_browsertest.h
+++ b/chrome/test/media_router/media_router_integration_browsertest.h
@@ -171,6 +171,13 @@
 
   void WaitUntilNoRoutes(content::WebContents* web_contents);
 
+  // Get the full path of the resource file.
+  // |relative_path|: The relative path to
+  //                  <chromium src>/out/<build config>/media_router/
+  //                  browser_test_resources/
+  base::FilePath GetResourceFile(
+      base::FilePath::StringPieceType relative_path) const;
+
   // Returns whether actual media route providers (as opposed to
   // TestMediaRouteProvider) should be loaded.
   virtual bool RequiresMediaRouteProviders() const;
@@ -193,13 +200,6 @@
   virtual Browser* browser();
 
  private:
-  // Get the full path of the resource file.
-  // |relative_path|: The relative path to
-  //                  <chromium src>/out/<build config>/media_router/
-  //                  browser_test_resources/
-  base::FilePath GetResourceFile(
-      base::FilePath::StringPieceType relative_path) const;
-
   std::unique_ptr<content::TestNavigationObserver> test_navigation_observer_;
   policy::MockConfigurationPolicyProvider provider_;
   base::test::ScopedFeatureList feature_list_;
diff --git a/chrome/version.gni b/chrome/version.gni
index 3375ca5..9bbb846 100644
--- a/chrome/version.gni
+++ b/chrome/version.gni
@@ -68,9 +68,6 @@
         "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" "
     if (target_cpu == "arm64") {
       _version_dictionary_template += "trichrome_64_32_high_version_code = \"@TRICHROME_64_32_HIGH_VERSION_CODE@\" "
-
-      # Deprecated.
-      _version_dictionary_template += "trichrome_64_high_version_code = \"@TRICHROME_64_HIGH_VERSION_CODE@\" "
     }
     _version_dictionary_template +=
         "trichrome_32_beta_version_code = \"@TRICHROME_32_BETA_VERSION_CODE@\" "
@@ -80,9 +77,6 @@
         "trichrome_64_beta_version_code = \"@TRICHROME_64_BETA_VERSION_CODE@\" "
     if (target_cpu == "arm64") {
       _version_dictionary_template += "trichrome_64_32_high_beta_version_code = \"@TRICHROME_64_32_HIGH_BETA_VERSION_CODE@\" "
-
-      # Deprecated.
-      _version_dictionary_template += "trichrome_64_high_beta_version_code = \"@TRICHROME_64_HIGH_BETA_VERSION_CODE@\" "
     }
     _version_dictionary_template +=
         "webview_32_stable_version_code = \"@WEBVIEW_32_STABLE_VERSION_CODE@\" "
@@ -156,14 +150,12 @@
                            "trichrome_64_32_high_version_code",
                            "trichrome_auto_64_32_version_code",
                            "trichrome_64_version_code",
-                           "trichrome_64_high_version_code",  # Deprecated.
                            "trichrome_beta_version_code",
                            "trichrome_32_beta_version_code",
                            "trichrome_32_64_beta_version_code",
                            "trichrome_64_32_beta_version_code",
                            "trichrome_64_32_high_beta_version_code",
                            "trichrome_64_beta_version_code",
-                           "trichrome_64_high_beta_version_code",  # Deprecated.
                            "webview_beta_version_code",
                            "webview_dev_version_code",
                            "webview_stable_version_code",
@@ -203,10 +195,8 @@
       "TrichromeChromeAuto6432: $trichrome_auto_64_32_version_code",
     ]
     if (target_cpu == "arm64") {
-      lines_to_write += [
-        "TrichromeChrome6432High: $trichrome_64_32_high_version_code",
-        "TrichromeChrome64High: $trichrome_64_high_version_code",  # Deprecated.
-      ]
+      lines_to_write +=
+          [ "TrichromeChrome6432High: $trichrome_64_32_high_version_code" ]
     }
     lines_to_write += [
       "TrichromeChrome32OpenBeta: $trichrome_32_beta_version_code",
@@ -215,12 +205,7 @@
       "TrichromeChrome64OpenBeta: $trichrome_64_beta_version_code",
     ]
     if (target_cpu == "arm64") {
-      lines_to_write += [
-        "TrichromeChrome6432HighOpenBeta: $trichrome_64_32_high_beta_version_code",
-
-        # Deprecated
-        "TrichromeChrome64HighOpenBeta: $trichrome_64_high_beta_version_code",
-      ]
+      lines_to_write += [ "TrichromeChrome6432HighOpenBeta: $trichrome_64_32_high_beta_version_code" ]
     }
     lines_to_write += [
       "AndroidWebview32Stable: $webview_32_stable_version_code",
@@ -257,21 +242,19 @@
       if (_use_stable_package_name_for_trichrome) {
         if (is_high_end_android) {
           true_true_true_true = trichrome_64_32_high_beta_version_code
-          true_true_true_false = trichrome_64_high_beta_version_code
         } else {
           true_true_true_true = trichrome_64_32_beta_version_code
-          true_true_true_false = trichrome_64_beta_version_code
         }
+        true_true_true_false = trichrome_64_beta_version_code
         true_false_false_true = trichrome_32_beta_version_code
         true_false_true_true = trichrome_32_64_beta_version_code
       } else {
         if (is_high_end_android) {
           true_true_true_true = trichrome_64_32_high_version_code
-          true_true_true_false = trichrome_64_high_version_code
         } else {
           true_true_true_true = trichrome_64_32_version_code
-          true_true_true_false = trichrome_64_version_code
         }
+        true_true_true_false = trichrome_64_version_code
         true_false_false_true = trichrome_32_version_code
         true_false_true_true = trichrome_32_64_version_code
       }
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index f7c3338..b3a8813 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -581,7 +581,6 @@
       "$root_gen_dir/chromecast/app/shell_resources.pak",
       "$root_gen_dir/components/cast/named_message_port_connector/named_message_port_connector_resources.pak",
       "$root_gen_dir/content/content_resources.pak",
-      "$root_gen_dir/content/dev_ui_content_resources.pak",
       "$root_gen_dir/content/gpu_resources.pak",
       "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
       "$root_gen_dir/net/net_resources.pak",
@@ -601,7 +600,6 @@
       "//chromecast/app:resources",
       "//components/cast/named_message_port_connector:resources",
       "//content:content_resources",
-      "//content:dev_ui_content_resources",
       "//content/browser/resources/gpu:resources",
       "//mojo/public/js:resources",
       "//net:net_resources",
diff --git a/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl.cc b/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl.cc
index a4d4241..123e1d4 100644
--- a/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl.cc
+++ b/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl.cc
@@ -58,22 +58,6 @@
   device_metadata->set_hardware_id(GetFullHardwareClass());
   device_metadata->set_market_segment(GetMarketSegment());
 
-  if (new_import_data_.empty()) {
-    LOG(ERROR) << "PSM Error - new import data is empty.";
-    base::Time cur_ts = GetActiveTs();
-    LOG(ERROR) << "Current timestamp = " << cur_ts;
-    LOG(ERROR) << "28DA Last Known Ping Timestamp = "
-               << GetLastKnownPingTimestamp();
-    SetPsmIdentifiersToImport(cur_ts);
-
-    if (new_import_data_.empty()) {
-      LOG(ERROR)
-          << "PSM Error - reattempt to set the psm id's to import failed.";
-      LOG(ERROR) << "Continuing to send empty import data body.";
-    }
-    base::debug::DumpWithoutCrashing();
-  }
-
   for (auto v : new_import_data_) {
     FresnelImportData* import_data = import_request.add_import_data();
     import_data->set_window_identifier(v.window_identifier());
@@ -138,12 +122,21 @@
   // Clear previous values of id's to import.
   new_import_data_.clear();
 
-  base::Time last_known_ping_ts = GetLastKnownPingTimestamp();
+  // Normalize current ts and last known ts to midnight.
+  // Not doing so will cause missing imports depending on the HH/MM/SS.
+  base::Time cur_ts_midnight = cur_ts.UTCMidnight();
+  base::Time last_known_ping_ts_midnight =
+      GetLastKnownPingTimestamp().UTCMidnight();
+
+  // Iterate from days [cur_ts, cur_ts+27], which represents the 28 day window.
   for (int i = 0; i < static_cast<int>(kRollingWindowSize); i++) {
-    base::Time day_n = cur_ts + base::Days(i);
+    base::Time day_n = cur_ts_midnight + base::Days(i);
 
     // Only generate import data for new identifiers to import.
-    if (day_n < (last_known_ping_ts + base::Days(kRollingWindowSize))) {
+    // last_known_ping_ts + 27 gives us the last day we previously sent an
+    // import data request for.
+    if (day_n <=
+        (last_known_ping_ts_midnight + base::Days(kRollingWindowSize - 1))) {
       continue;
     }
 
@@ -164,14 +157,6 @@
     new_import_data_.push_back(import_data);
   }
 
-  // Add logs if |new_import_data_| is empty.
-  if (new_import_data_.empty()) {
-    LOG(ERROR) << "Current timestamp = " << GetActiveTs();
-    LOG(ERROR) << "28DA Last Known Ping Timestamp = "
-               << GetLastKnownPingTimestamp();
-    base::debug::DumpWithoutCrashing();
-  }
-
   return true;
 }
 
diff --git a/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl_unittest.cc b/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl_unittest.cc
index eaf4414..9a1b14a 100644
--- a/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl_unittest.cc
+++ b/chromeos/ash/components/device_activity/twenty_eight_day_active_use_case_impl_unittest.cc
@@ -350,9 +350,7 @@
   std::vector<FresnelImportData> import_data =
       twenty_eight_day_active_use_case_impl_->GetImportData();
 
-  // Client should only import for the new day 20220108.
   EXPECT_EQ(import_data.size(), 1u);
-
   std::vector<std::string> expected_window_ids = {"20220129"};
 
   for (auto& v : import_data) {
@@ -363,6 +361,59 @@
 }
 
 TEST_F(TwentyEightDayActiveUseCaseImplTest,
+       CheckInPartialRollingWindowOnDeviceThatReportedTwoDaysAgo) {
+  base::Time ts;
+  EXPECT_TRUE(base::Time::FromString("01 Jan 2022 00:00:00 GMT", &ts));
+  twenty_eight_day_active_use_case_impl_->SetLastKnownPingTimestamp(ts);
+
+  // Update current ts to 20220103
+  EXPECT_TRUE(base::Time::FromString("03 Jan 2022 00:00:00 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data.size(), 2u);
+
+  std::vector<std::string> expected_window_ids = {"20220129", "20220130"};
+
+  for (auto& v : import_data) {
+    EXPECT_TRUE(std::find(expected_window_ids.begin(),
+                          expected_window_ids.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+}
+
+TEST_F(TwentyEightDayActiveUseCaseImplTest,
+       CheckInPartialRollingWindowOnDeviceThatReportedTwentyEightDaysAgo) {
+  base::Time ts;
+  EXPECT_TRUE(base::Time::FromString("01 Jan 2022 00:00:00 GMT", &ts));
+  twenty_eight_day_active_use_case_impl_->SetLastKnownPingTimestamp(ts);
+
+  // Update current ts to 20220127
+  EXPECT_TRUE(base::Time::FromString("28 Jan 2022 00:00:00 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data.size(), 27u);
+
+  std::vector<std::string> expected_window_ids = {
+      "20220129", "20220130", "20220131", "20220201", "20220202", "20220203",
+      "20220204", "20220205", "20220206", "20220207", "20220208", "20220209",
+      "20220210", "20220211", "20220212", "20220213", "20220214", "20220215",
+      "20220216", "20220217", "20220218", "20220219", "20220220", "20220221",
+      "20220222", "20220223", "20220224"};
+
+  for (auto& v : import_data) {
+    EXPECT_TRUE(std::find(expected_window_ids.begin(),
+                          expected_window_ids.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+}
+
+TEST_F(TwentyEightDayActiveUseCaseImplTest,
        CheckInEmptyOnDeviceThatReportedFuture) {
   base::Time ts;
   EXPECT_TRUE(base::Time::FromString("03 Jan 2022 00:00:00 GMT", &ts));
@@ -381,4 +432,79 @@
   EXPECT_EQ(import_data.size(), 0u);
 }
 
+TEST_F(TwentyEightDayActiveUseCaseImplTest, CheckInSingleDayInMiddleOfYear) {
+  base::Time ts;
+  EXPECT_TRUE(base::Time::FromString("04 May 2023 00:04:22.962 GMT", &ts));
+  twenty_eight_day_active_use_case_impl_->SetLastKnownPingTimestamp(ts);
+
+  EXPECT_TRUE(base::Time::FromString("05 May 2023 00:00:20.924 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data.size(), 1u);
+  std::vector<std::string> expected_window_ids = {"20230601"};
+
+  for (auto& v : import_data) {
+    EXPECT_TRUE(std::find(expected_window_ids.begin(),
+                          expected_window_ids.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+}
+
+TEST_F(TwentyEightDayActiveUseCaseImplTest, CheckInSingleDayWithVaryingHours) {
+  base::Time ts;
+  EXPECT_TRUE(base::Time::FromString("04 May 2023 00:00:22.962 GMT", &ts));
+  twenty_eight_day_active_use_case_impl_->SetLastKnownPingTimestamp(ts);
+
+  // Test when last known ping ts hour is smaller than current ts hour.
+  EXPECT_TRUE(base::Time::FromString("05 May 2023 00:04:20.924 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data.size(), 1u);
+  std::vector<std::string> expected_window_ids = {"20230601"};
+
+  for (auto& v : import_data) {
+    EXPECT_TRUE(std::find(expected_window_ids.begin(),
+                          expected_window_ids.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+
+  // Test when last known ping ts hour is equal to current ts hour.
+  EXPECT_TRUE(base::Time::FromString("05 May 2023 00:00:22.962 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data_2 =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data_2.size(), 1u);
+  std::vector<std::string> expected_window_ids_2 = {"20230601"};
+
+  for (auto& v : import_data_2) {
+    EXPECT_TRUE(std::find(expected_window_ids_2.begin(),
+                          expected_window_ids_2.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+
+  // Test when last known ping ts hour is greater than current ts hour.
+  EXPECT_TRUE(base::Time::FromString("05 May 2023 23:59:59.000 GMT", &ts));
+  EXPECT_TRUE(twenty_eight_day_active_use_case_impl_->SetWindowIdentifier(ts));
+
+  std::vector<FresnelImportData> import_data_3 =
+      twenty_eight_day_active_use_case_impl_->GetImportData();
+
+  EXPECT_EQ(import_data_3.size(), 1u);
+  std::vector<std::string> expected_window_ids_3 = {"20230601"};
+
+  for (auto& v : import_data_3) {
+    EXPECT_TRUE(std::find(expected_window_ids_3.begin(),
+                          expected_window_ids_3.end(),
+                          v.window_identifier()) != expected_window_ids.end());
+  }
+}
+
 }  // namespace ash::device_activity
diff --git a/chromeos/crosapi/mojom/download_status_updater.mojom b/chromeos/crosapi/mojom/download_status_updater.mojom
index a31b753..81d43f44 100644
--- a/chromeos/crosapi/mojom/download_status_updater.mojom
+++ b/chromeos/crosapi/mojom/download_status_updater.mojom
@@ -5,13 +5,13 @@
 module crosapi.mojom;
 
 import "chromeos/crosapi/mojom/download_controller.mojom";
+import "mojo/public/mojom/base/file_path.mojom";
 
-// TODO(http://b/279831939): Add more renderable metadata.
 // Representation of a Lacros download's status to be passed into Ash Chrome
 // and rendered in the appropriate System UI surface(s).
 //
-// Next MinVersion: 1
-// Next ID: 2
+// Next MinVersion: 2
+// Next ID: 8
 //
 [Stable, Uuid="d18b6479-e70d-44aa-b657-58ffff57735d"]
 struct DownloadStatus {
@@ -23,6 +23,29 @@
   // The current state of the underlying download.
   DownloadState state@1;
 
+  // The total number of bytes that have been received and written to the
+  // underlying download file.
+  [MinVersion=1] int64? received_bytes@2;
+
+  // The total number of bytes expected to be written to the underlying download
+  // file, or -1 if the total number of bytes is unknown.
+  [MinVersion=1] int64? total_bytes@3;
+
+  // The target path of an in-progress download. Note that the actual path being
+  // written to may be that of a temporary or intermediate file, but the target
+  // path will be used once the underlying download completes. Also note that
+  // the target path may be empty if it hasn't yet been determined.
+  [MinVersion=1] mojo_base.mojom.FilePath? target_file_path@4;
+
+  // Whether an in-progress download can be cancelled by the user.
+  [MinVersion=1] bool? cancellable@5;
+
+  // Whether an in-progress download can be paused by the user.
+  [MinVersion=1] bool? pausable@6;
+
+  // Whether an in-progress download can be resumed by the user.
+  [MinVersion=1] bool? resumable@7;
+
 };
 
 // The interface which allows Lacros download status updates to be passed into
diff --git a/chromeos/dbus/power/fake_power_manager_client.cc b/chromeos/dbus/power/fake_power_manager_client.cc
index 7ebbdf3..4e6cb825 100644
--- a/chromeos/dbus/power/fake_power_manager_client.cc
+++ b/chromeos/dbus/power/fake_power_manager_client.cc
@@ -293,7 +293,18 @@
 
 void FakePowerManagerClient::SetBatterySaverModeState(
     const power_manager::SetBatterySaverModeStateRequest& request) {
+  bool changed = battery_saver_mode_enabled_ != request.enabled();
+  if (!changed) {
+    return;
+  }
+
   battery_saver_mode_enabled_ = request.enabled();
+
+  power_manager::BatterySaverModeState state;
+  state.set_enabled(battery_saver_mode_enabled_);
+  for (auto& observer : observers_) {
+    observer.BatterySaverModeStateChanged(state);
+  }
 }
 
 void FakePowerManagerClient::GetSwitchStates(
diff --git a/chromeos/ui/base/window_properties.cc b/chromeos/ui/base/window_properties.cc
index 262c0c9..76ee889 100644
--- a/chromeos/ui/base/window_properties.cc
+++ b/chromeos/ui/base/window_properties.cc
@@ -24,6 +24,7 @@
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kEscHoldToExitFullscreen, false)
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kUseOverviewToExitFullscreen, false)
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kUseOverviewToExitPointerLock, false)
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kNoExitFullscreenOnLock, false)
 
 DEFINE_UI_CLASS_PROPERTY_KEY(bool, kTrackDefaultFrameColors, true)
 DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, kFrameActiveColorKey, kDefaultFrameColor)
diff --git a/chromeos/ui/base/window_properties.h b/chromeos/ui/base/window_properties.h
index ddc3fae0..5c02b744 100644
--- a/chromeos/ui/base/window_properties.h
+++ b/chromeos/ui/base/window_properties.h
@@ -38,6 +38,14 @@
 COMPONENT_EXPORT(CHROMEOS_UI_BASE)
 extern const ui::ClassProperty<bool>* const kEscHoldToExitFullscreen;
 
+// Do not exit fullscreen on a screen lock. Note that this property becomes
+// active only if `kUseOverviewToExitFullscreen` is true. Borealis apps set this
+// to avoid exiting fullscreen on a screen lock.
+// Do NOT use this property without consulting the security team for other use
+// cases.
+COMPONENT_EXPORT(CHROMEOS_UI_BASE)
+extern const ui::ClassProperty<bool>* const kNoExitFullscreenOnLock;
+
 // Whether to promote users to use Overview to exit fullscreen.
 // Borealis apps set this since they do not handle window size changes.
 COMPONENT_EXPORT(CHROMEOS_UI_BASE)
diff --git a/components/browsing_data/content/browsing_data_helper.cc b/components/browsing_data/content/browsing_data_helper.cc
index 4e97d3fd..2640813 100644
--- a/components/browsing_data/content/browsing_data_helper.cc
+++ b/components/browsing_data/content/browsing_data_helper.cc
@@ -7,6 +7,7 @@
 #include <vector>
 
 #include "base/containers/contains.h"
+#include "base/functional/overloaded.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/content_settings/core/browser/content_settings_registry.h"
@@ -205,10 +206,13 @@
 int GetUniqueHostCount(
     const browsing_data::LocalSharedObjectsContainer& local_shared_objects,
     const BrowsingDataModel& browsing_data_model) {
-  std::set<std::string> unique_hosts = local_shared_objects.GetHosts();
+  std::set<BrowsingDataModel::DataOwner> unique_hosts;
+  for (const std::string& host : local_shared_objects.GetHosts()) {
+    unique_hosts.insert(host);
+  }
 
   for (auto entry : browsing_data_model) {
-    unique_hosts.insert(entry.primary_host.get());
+    unique_hosts.insert(*entry.data_owner);
   }
 
   return unique_hosts.size();
diff --git a/components/browsing_data/content/browsing_data_model.cc b/components/browsing_data/content/browsing_data_model.cc
index f1a07b4..42537acc 100644
--- a/components/browsing_data/content/browsing_data_model.cc
+++ b/components/browsing_data/content/browsing_data_model.cc
@@ -7,6 +7,7 @@
 #include "base/barrier_closure.h"
 #include "base/containers/enum_set.h"
 #include "base/functional/callback.h"
+#include "base/functional/overloaded.h"
 #include "base/memory/weak_ptr.h"
 #include "components/browsing_data/content/browsing_data_quota_helper.h"
 #include "components/browsing_data/core/features.h"
@@ -34,36 +35,47 @@
 // An estimate of storage size of an Interest Group object.
 constexpr int kModerateAmountOfDataInBytes = 1024;
 
-// Visitor which returns the appropriate primary host for a given `data_key`
+// Visitor which returns the appropriate data owner for a given `data_key`
 // and `storage_type`.
-struct GetPrimaryHost {
-  explicit GetPrimaryHost(BrowsingDataModel::StorageType storage_type)
-      : storage_type_(storage_type) {}
+struct GetDataOwner {
+  GetDataOwner(BrowsingDataModel::Delegate* delegate,
+               BrowsingDataModel::StorageType storage_type)
+      : delegate_(delegate), storage_type_(storage_type) {}
 
   template <class T>
-  std::string operator()(const T& data_key) const;
+  BrowsingDataModel::DataOwner operator()(const T& data_key) const {
+    if (delegate_) {
+      absl::optional<BrowsingDataModel::DataOwner> owner =
+          delegate_->GetDataOwner(data_key, storage_type_);
+      if (owner.has_value()) {
+        return *owner;
+      }
+    }
+    // By default all data is owned by its host.
+    return GetOwningHost(data_key);
+  }
 
  private:
+  template <class T>
+  std::string GetOwningHost(const T& data_key) const;
+
+  raw_ptr<BrowsingDataModel::Delegate> delegate_;
   BrowsingDataModel::StorageType storage_type_;
 };
 
 template <>
-std::string GetPrimaryHost::operator()<url::Origin>(
+std::string GetDataOwner::GetOwningHost<url::Origin>(
     const url::Origin& data_key) const {
   if (storage_type_ == BrowsingDataModel::StorageType::kTrustTokens) {
     return data_key.host();
   }
 
-  if (storage_type_ > BrowsingDataModel::StorageType::kLastType) {
-    return data_key.host();
-  }
-
-  NOTREACHED();
+  NOTREACHED() << "Unexpected StorageType: " << static_cast<int>(storage_type_);
   return "";
 }
 
 template <>
-std::string GetPrimaryHost::operator()<blink::StorageKey>(
+std::string GetDataOwner::GetOwningHost<blink::StorageKey>(
     const blink::StorageKey& data_key) const {
   // TODO(crbug.com/1271155): This logic is useful for testing during the
   // implementation of the model, but ultimately these storage types may not
@@ -79,20 +91,20 @@
   if (storage_type_ == BrowsingDataModel::StorageType::kSharedStorage) {
     return data_key.origin().host();
   }
-  NOTREACHED();
+  NOTREACHED() << "Unexpected StorageType: " << static_cast<int>(storage_type_);
   return "";
 }
 
 template <>
-std::string
-GetPrimaryHost::operator()<content::InterestGroupManager::InterestGroupDataKey>(
+std::string GetDataOwner::GetOwningHost<
+    content::InterestGroupManager::InterestGroupDataKey>(
     const content::InterestGroupManager::InterestGroupDataKey& data_key) const {
   DCHECK_EQ(BrowsingDataModel::StorageType::kInterestGroup, storage_type_);
   return data_key.owner.host();
 }
 
 template <>
-std::string GetPrimaryHost::operator()<content::AttributionDataModel::DataKey>(
+std::string GetDataOwner::GetOwningHost<content::AttributionDataModel::DataKey>(
     const content::AttributionDataModel::DataKey& data_key) const {
   DCHECK_EQ(BrowsingDataModel::StorageType::kAttributionReporting,
             storage_type_);
@@ -113,7 +125,7 @@
         delegate_(delegate) {}
 
   void RemoveByPrimaryHost(
-      const std::string& primary_host,
+      const BrowsingDataModel::DataOwner& data_owner,
       const BrowsingDataModel::DataKeyEntries& data_key_entries,
       base::OnceClosure completed);
 
@@ -146,7 +158,7 @@
 };
 
 void StorageRemoverHelper::RemoveByPrimaryHost(
-    const std::string& primary_host,
+    const BrowsingDataModel::DataOwner& data_owner,
     const BrowsingDataModel::DataKeyEntries& data_key_entries,
     base::OnceClosure completed) {
   // At a helper level, only a single deletion may occur at a time. However
@@ -162,7 +174,10 @@
   auto sync_completion = GetCompleteCallback();
   for (const auto& [key, details] : data_key_entries) {
     absl::visit(Visitor{this, details.storage_types}, key);
-    delegate_->RemoveDataKey(key, details.storage_types, GetCompleteCallback());
+    if (delegate_) {
+      delegate_->RemoveDataKey(key, details.storage_types,
+                               GetCompleteCallback());
+    }
   }
 
   std::move(sync_completion).Run();
@@ -348,14 +363,23 @@
 }
 
 BrowsingDataModel::BrowsingDataEntryView::BrowsingDataEntryView(
-    const std::string& primary_host,
+    const DataOwner& data_owner,
     const DataKey& data_key,
     const DataDetails& data_details)
-    : primary_host(primary_host),
-      data_key(data_key),
-      data_details(data_details) {}
+    : data_owner(data_owner), data_key(data_key), data_details(data_details) {}
 BrowsingDataModel::BrowsingDataEntryView::~BrowsingDataEntryView() = default;
 
+bool BrowsingDataModel::BrowsingDataEntryView::Matches(
+    const url::Origin& origin) const {
+  return absl::visit(base::Overloaded{[&](const std::string& entry_host) {
+                                        return entry_host == origin.host();
+                                      },
+                                      [&](const url::Origin& entry_origin) {
+                                        return entry_origin == origin;
+                                      }},
+                     *data_owner);
+}
+
 BrowsingDataModel::Delegate::DelegateEntry::DelegateEntry(
     DataKey data_key,
     StorageType storage_type,
@@ -475,18 +499,18 @@
                                         StorageType storage_type,
                                         uint64_t storage_size,
                                         uint64_t cookie_count) {
-  std::string primary_host =
-      absl::visit(GetPrimaryHost(storage_type), data_key);
+  DataOwner data_owner =
+      absl::visit(GetDataOwner(delegate_.get(), storage_type), data_key);
 
   // Find the existing entry if it exists, constructing any missing components.
-  auto& entry = browsing_data_entries_[primary_host][data_key];
+  auto& entry = browsing_data_entries_[data_owner][data_key];
 
   entry.storage_size += storage_size;
   entry.cookie_count += cookie_count;
   entry.storage_types.Put(storage_type);
 }
 
-void BrowsingDataModel::RemoveBrowsingData(const std::string& primary_host,
+void BrowsingDataModel::RemoveBrowsingData(const DataOwner& data_owner,
                                            base::OnceClosure completed) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
@@ -500,14 +524,14 @@
          base::OnceClosure completed) { std::move(completed).Run(); },
       std::move(helper), std::move(completed));
 
-  helper_pointer->RemoveByPrimaryHost(primary_host,
-                                      browsing_data_entries_[primary_host],
+  helper_pointer->RemoveByPrimaryHost(data_owner,
+                                      browsing_data_entries_[data_owner],
                                       std::move(wrapped_completed));
 
   // Immediately remove the affected entries from the in-memory model. Different
   // UI elements have different sync vs. async expectations. Exposing a
   // completed callback, but updating the model synchronously, serves both.
-  browsing_data_entries_.erase(primary_host);
+  browsing_data_entries_.erase(data_owner);
 }
 
 void BrowsingDataModel::PopulateFromDisk(base::OnceClosure finished_callback) {
@@ -573,8 +597,10 @@
   }
 
   // Data loaded from non-components storage types via the delegate.
-  delegate_->GetAllDataKeys(
-      base::BindOnce(&OnDelegateDataLoaded, this, completion));
+  if (delegate_) {
+    delegate_->GetAllDataKeys(
+        base::BindOnce(&OnDelegateDataLoaded, this, completion));
+  }
 }
 
 BrowsingDataModel::BrowsingDataModel(
diff --git a/components/browsing_data/content/browsing_data_model.h b/components/browsing_data/content/browsing_data_model.h
index 8acc53b5..ac15661 100644
--- a/components/browsing_data/content/browsing_data_model.h
+++ b/components/browsing_data/content/browsing_data_model.h
@@ -26,11 +26,16 @@
 
 // Provides a model interface into a collection of Browsing Data for use in the
 // UI. Exposes a uniform view into browsing data based on the concept of
-// "primary hosts", which denote which host the data should be closely
+// "data owners", which denote which entity the data should be closely
 // associated with in UI surfaces.
 // TODO(crbug.com/1271155): Implementation in progress, should not be used.
 class BrowsingDataModel {
  public:
+  // The entity that logically owns a set of data. All browsing data will be
+  // grouped by its owner.
+  using DataOwner = absl::variant<std::string,  // Hostname
+                                  url::Origin>;
+
   // Storage types which are represented by the model. Some types have
   // incomplete implementations, and are marked as such.
   // TODO(crbug.com/1271155): Complete implementations for all browsing data.
@@ -86,9 +91,12 @@
     ~BrowsingDataEntryView();
     BrowsingDataEntryView(const BrowsingDataEntryView& other) = delete;
 
-    // The primary host for this browsing data. This is the host which this
+    // Returns true if |origin| is within this browsing data's  owning entity.
+    bool Matches(const url::Origin& origin) const;
+
+    // The logical owner of this browsing data. This is the entity which this
     // information will be most strongly associated with in UX surfaces.
-    const raw_ref<const std::string, DanglingUntriaged> primary_host;
+    const raw_ref<const DataOwner, DanglingUntriaged> data_owner;
 
     // The unique identifier for the data represented by this entry.
     const raw_ref<const DataKey, DanglingUntriaged> data_key;
@@ -99,7 +107,7 @@
    private:
     friend class BrowsingDataModel;
 
-    BrowsingDataEntryView(const std::string& primary_host,
+    BrowsingDataEntryView(const DataOwner& data_owner,
                           const DataKey& data_key,
                           const DataDetails& data_details);
   };
@@ -126,6 +134,12 @@
     virtual void RemoveDataKey(DataKey data_key,
                                StorageTypeSet storage_types,
                                base::OnceClosure callback) = 0;
+    // Returns the owner of the data identified by the given DataKey and
+    // StorageType, or nullopt if the delegate does not manage the entity that
+    // owns the given data.
+    virtual absl::optional<DataOwner> GetDataOwner(
+        DataKey data_key,
+        StorageType storage_type) const = 0;
     virtual ~Delegate() = default;
   };
 
@@ -134,7 +148,7 @@
   // over BrowsingDataEntryViews.
   // Iterators are invalidated whenever the model is updated.
   using DataKeyEntries = std::map<DataKey, DataDetails>;
-  using BrowsingDataEntries = std::map<std::string, DataKeyEntries>;
+  using BrowsingDataEntries = std::map<DataOwner, DataKeyEntries>;
   struct Iterator {
     ~Iterator();
     Iterator(const Iterator& iterator);
@@ -201,16 +215,16 @@
                        // TODO(crbug.com/1359998): Deprecate cookie count.
                        uint64_t cookie_count = 0);
 
-  // Removes all browsing data associated with `primary_host`, reaches out to
+  // Removes all browsing data associated with `data_owner`, reaches out to
   // all supported storage backends to remove the data, and updates the model.
-  // Deletion at more granularity than `primary_host` is purposefully not
+  // Deletion at more granularity than `data_owner` is purposefully not
   // supported by this model. UI that wishes to support such deletion should
   // consider whether it is really required, and if so, implement it separately.
   // The in-memory representation of the model is updated immediately, while
   // actual deletion from disk occurs async, completion reported by `completed`.
   // Invalidates any iterators.
   // Virtual to allow an in-memory only fake to be created.
-  virtual void RemoveBrowsingData(const std::string& primary_host,
+  virtual void RemoveBrowsingData(const DataOwner& data_owner,
                                   base::OnceClosure completed);
 
  protected:
@@ -233,11 +247,11 @@
   // Virtual to allow an in-memory only fake to be created.
   virtual void PopulateFromDisk(base::OnceClosure finished_callback);
 
-  // Backing data structure for this model. Is a map from primary hosts to a
+  // Backing data structure for this model. Is a map from data owners to a
   // list of tuples (stored as a map) of <DataKey, DataDetails>. Building the
-  // model required updating existing entries as data becomes available, so
-  // fast lookup is required. Similarly, keying the outer map on primary host
-  // supports removal by primary host performantly.
+  // model requires updating existing entries as data becomes available, so
+  // fast lookup is required. Similarly, keying the outer map on data owner
+  // supports removal by data owner performantly.
   BrowsingDataEntries browsing_data_entries_;
 
   // Non-owning pointers to storage backends. All derivable from a browser
diff --git a/components/browsing_data/content/browsing_data_model_test_util.cc b/components/browsing_data/content/browsing_data_model_test_util.cc
index 486f5296..54d6bc4e 100644
--- a/components/browsing_data/content/browsing_data_model_test_util.cc
+++ b/components/browsing_data/content/browsing_data_model_test_util.cc
@@ -10,16 +10,14 @@
 namespace browsing_data_model_test_util {
 
 BrowsingDataEntry::BrowsingDataEntry(
-    const std::string& primary_host,
+    const BrowsingDataModel::DataOwner& data_owner,
     BrowsingDataModel::DataKey data_key,
     BrowsingDataModel::DataDetails data_details)
-    : primary_host(primary_host),
-      data_key(data_key),
-      data_details(data_details) {}
+    : data_owner(data_owner), data_key(data_key), data_details(data_details) {}
 
 BrowsingDataEntry::BrowsingDataEntry(
     const BrowsingDataModel::BrowsingDataEntryView& view)
-    : primary_host(*view.primary_host),
+    : data_owner(*view.data_owner),
       data_key(*view.data_key),
       data_details(*view.data_details) {}
 
@@ -27,7 +25,7 @@
 BrowsingDataEntry::BrowsingDataEntry(const BrowsingDataEntry& other) = default;
 
 bool BrowsingDataEntry::operator==(const BrowsingDataEntry& other) const {
-  return primary_host == other.primary_host && data_key == other.data_key &&
+  return data_owner == other.data_owner && data_key == other.data_key &&
          data_details == other.data_details;
 }
 
@@ -40,8 +38,8 @@
     model_entries.emplace_back(entry);
   }
 
-  EXPECT_THAT(expected_entries,
-              testing::UnorderedElementsAreArray(model_entries));
+  EXPECT_THAT(model_entries,
+              testing::UnorderedElementsAreArray(expected_entries));
 }
 
 void ValidateBrowsingDataEntriesIgnoreUsage(
@@ -54,7 +52,7 @@
   EXPECT_EQ(model_entries.size(), expected_entries.size());
 
   for (size_t i = 0; i < expected_entries.size(); i++) {
-    EXPECT_EQ(expected_entries[i].primary_host, model_entries[i].primary_host);
+    EXPECT_EQ(expected_entries[i].data_owner, model_entries[i].data_owner);
     EXPECT_EQ(expected_entries[i].data_key, model_entries[i].data_key);
     EXPECT_EQ(expected_entries[i].data_details.storage_types,
               model_entries[i].data_details.storage_types);
diff --git a/components/browsing_data/content/browsing_data_model_test_util.h b/components/browsing_data/content/browsing_data_model_test_util.h
index c9d01a9a..114698c 100644
--- a/components/browsing_data/content/browsing_data_model_test_util.h
+++ b/components/browsing_data/content/browsing_data_model_test_util.h
@@ -12,7 +12,7 @@
 // For testing purposes, it's useful to have a non-view version of a
 // BrowsingDataEntry, so they can be put in vectors etc.
 struct BrowsingDataEntry {
-  BrowsingDataEntry(const std::string& primary_host,
+  BrowsingDataEntry(const BrowsingDataModel::DataOwner& data_owner,
                     BrowsingDataModel::DataKey data_key,
                     BrowsingDataModel::DataDetails data_details);
   explicit BrowsingDataEntry(
@@ -21,7 +21,7 @@
   BrowsingDataEntry(const BrowsingDataEntry& other);
   bool operator==(const BrowsingDataEntry& other) const;
 
-  std::string primary_host;
+  BrowsingDataModel::DataOwner data_owner;
   BrowsingDataModel::DataKey data_key;
   BrowsingDataModel::DataDetails data_details;
 };
diff --git a/components/browsing_data/content/browsing_data_model_unittest.cc b/components/browsing_data/content/browsing_data_model_unittest.cc
index 40866b14..1cdda69 100644
--- a/components/browsing_data/content/browsing_data_model_unittest.cc
+++ b/components/browsing_data/content/browsing_data_model_unittest.cc
@@ -124,7 +124,7 @@
 
 TEST_F(BrowsingDataModelTest, EntryCoalescense) {
   // Check that multiple entries are correctly coalesced.
-  // Browsing data with the same primary_host + data_key pair should update the
+  // Browsing data with the same owner + data_key pair should update the
   // same entry's details.
   model()->AddBrowsingData(
       blink::StorageKey::CreateFirstParty(kSiteOrigin),
@@ -143,7 +143,7 @@
 
   ValidateBrowsingDataEntries(model(), expected_entries);
 
-  // Entries related to the same primary_host, but different data_keys, should
+  // Entries related to the same owner, but different data_keys, should
   // create a new entry.
   model()->AddBrowsingData(
       blink::StorageKey::CreateFirstParty(kAnotherSiteOrigin),
@@ -304,4 +304,75 @@
   // Model should be empty after deleting delegated data.
   browsing_data_model_test_util::ValidateBrowsingDataEntries(model(),
                                                              expected_entries);
-}
\ No newline at end of file
+}
+
+// A BrowsingDataModel::Delegate that marks all Origin-keyed data belonging
+// to a given host as being owned by its origin rather than its host.
+class OriginOwnershipDelegate : public BrowsingDataModel::Delegate {
+ public:
+  explicit OriginOwnershipDelegate(const std::string& origin_owned_host)
+      : origin_owned_host_(origin_owned_host) {}
+
+  // BrowsingDataModel::Delegate:
+  void GetAllDataKeys(
+      base::OnceCallback<void(std::vector<DelegateEntry>)> callback) override {
+    std::move(callback).Run({});
+  }
+
+  void RemoveDataKey(BrowsingDataModel::DataKey data_key,
+                     BrowsingDataModel::StorageTypeSet storage_types,
+                     base::OnceClosure callback) override {
+    std::move(callback).Run();
+  }
+
+  absl::optional<BrowsingDataModel::DataOwner> GetDataOwner(
+      BrowsingDataModel::DataKey data_key,
+      BrowsingDataModel::StorageType storage_type) const override {
+    url::Origin* origin = absl::get_if<url::Origin>(&data_key);
+    if (origin && origin->host() == origin_owned_host_) {
+      return *origin;
+    }
+    return absl::nullopt;
+  }
+
+ private:
+  std::string origin_owned_host_;
+};
+
+TEST_F(BrowsingDataModelTest, DelegateDataCanBeOriginOwned) {
+  std::string origin_owned_host = "origin.owned.com";
+  std::unique_ptr<BrowsingDataModel> model = BrowsingDataModel::BuildEmpty(
+      storage_partition(),
+      std::make_unique<OriginOwnershipDelegate>(origin_owned_host));
+
+  auto httpOriginOwned = url::Origin::Create(GURL("http://origin.owned.com"));
+  model->AddBrowsingData(httpOriginOwned,
+                         BrowsingDataModel::StorageType::kTrustTokens, 100);
+  auto httpsOriginOwned = url::Origin::Create(GURL("https://origin.owned.com"));
+  model->AddBrowsingData(httpsOriginOwned,
+                         BrowsingDataModel::StorageType::kTrustTokens, 100);
+  auto httpHostOwned = url::Origin::Create(GURL("http://host.owned.com"));
+  model->AddBrowsingData(httpHostOwned,
+                         BrowsingDataModel::StorageType::kTrustTokens, 100);
+  auto httpsHostOwned = url::Origin::Create(GURL("https://host.owned.com"));
+  model->AddBrowsingData(httpsHostOwned,
+                         BrowsingDataModel::StorageType::kTrustTokens, 100);
+
+  auto expected_entries = std::vector<BrowsingDataEntry>{
+      {httpOriginOwned,
+       httpOriginOwned,
+       {BrowsingDataModel::StorageType::kTrustTokens, 100, 0}},
+      {httpsOriginOwned,
+       httpsOriginOwned,
+       {BrowsingDataModel::StorageType::kTrustTokens, 100, 0}},
+      {"host.owned.com",
+       httpHostOwned,
+       {BrowsingDataModel::StorageType::kTrustTokens, 100, 0}},
+      {"host.owned.com",
+       httpsHostOwned,
+       {BrowsingDataModel::StorageType::kTrustTokens, 100, 0}},
+  };
+
+  browsing_data_model_test_util::ValidateBrowsingDataEntries(model.get(),
+                                                             expected_entries);
+}
diff --git a/components/browsing_data/content/fake_browsing_data_model.cc b/components/browsing_data/content/fake_browsing_data_model.cc
index 25448e9e..340ed553 100644
--- a/components/browsing_data/content/fake_browsing_data_model.cc
+++ b/components/browsing_data/content/fake_browsing_data_model.cc
@@ -5,12 +5,15 @@
 #include "components/browsing_data/content/fake_browsing_data_model.h"
 
 FakeBrowsingDataModel::FakeBrowsingDataModel()
-    : BrowsingDataModel(nullptr, nullptr) {}
+    : FakeBrowsingDataModel(/*delegate=*/nullptr) {}
+FakeBrowsingDataModel::FakeBrowsingDataModel(
+    std::unique_ptr<BrowsingDataModel::Delegate> delegate)
+    : BrowsingDataModel(nullptr, std::move(delegate)) {}
 FakeBrowsingDataModel::~FakeBrowsingDataModel() = default;
 
-void FakeBrowsingDataModel::RemoveBrowsingData(const std::string& primary_host,
+void FakeBrowsingDataModel::RemoveBrowsingData(const DataOwner& data_owner,
                                                base::OnceClosure completed) {
-  browsing_data_entries_.erase(primary_host);
+  browsing_data_entries_.erase(data_owner);
 }
 
 void FakeBrowsingDataModel::PopulateFromDisk(
diff --git a/components/browsing_data/content/fake_browsing_data_model.h b/components/browsing_data/content/fake_browsing_data_model.h
index 73dd0bca..4a248185 100644
--- a/components/browsing_data/content/fake_browsing_data_model.h
+++ b/components/browsing_data/content/fake_browsing_data_model.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
+#include "base/functional/callback_forward.h"
 #include "components/browsing_data/content/browsing_data_model.h"
 
 #ifndef COMPONENTS_BROWSING_DATA_CONTENT_FAKE_BROWSING_DATA_MODEL_H_
@@ -12,10 +15,12 @@
 // any function which would attempt to fetch from disk.
 class FakeBrowsingDataModel : public BrowsingDataModel {
  public:
-  explicit FakeBrowsingDataModel();
+  FakeBrowsingDataModel();
+  explicit FakeBrowsingDataModel(
+      std::unique_ptr<BrowsingDataModel::Delegate> delegate);
   ~FakeBrowsingDataModel() override;
 
-  void RemoveBrowsingData(const std::string& primary_host,
+  void RemoveBrowsingData(const DataOwner& data_owner,
                           base::OnceClosure completed) override;
 
  private:
diff --git a/components/browsing_data/content/test_browsing_data_model_delegate.cc b/components/browsing_data/content/test_browsing_data_model_delegate.cc
index b0d5ba39..93c385e 100644
--- a/components/browsing_data/content/test_browsing_data_model_delegate.cc
+++ b/components/browsing_data/content/test_browsing_data_model_delegate.cc
@@ -34,4 +34,16 @@
   std::move(callback).Run();
 }
 
-}  // namespace browsing_data
\ No newline at end of file
+absl::optional<BrowsingDataModel::DataOwner>
+TestBrowsingDataModelDelegate::GetDataOwner(
+    BrowsingDataModel::DataKey data_key,
+    BrowsingDataModel::StorageType storage_type) const {
+  if (static_cast<StorageType>(storage_type) ==
+          StorageType::kTestDelegateType &&
+      absl::holds_alternative<url::Origin>(data_key)) {
+    return absl::get<url::Origin>(data_key).host();
+  }
+  return absl::nullopt;
+}
+
+}  // namespace browsing_data
diff --git a/components/browsing_data/content/test_browsing_data_model_delegate.h b/components/browsing_data/content/test_browsing_data_model_delegate.h
index 2e58e0cb..c174f3c 100644
--- a/components/browsing_data/content/test_browsing_data_model_delegate.h
+++ b/components/browsing_data/content/test_browsing_data_model_delegate.h
@@ -24,6 +24,9 @@
   void RemoveDataKey(BrowsingDataModel::DataKey data_key,
                      BrowsingDataModel::StorageTypeSet storage_types,
                      base::OnceClosure callback) override;
+  absl::optional<BrowsingDataModel::DataOwner> GetDataOwner(
+      BrowsingDataModel::DataKey data_key,
+      BrowsingDataModel::StorageType storage_type) const override;
 
  private:
   std::map<BrowsingDataModel::DataKey, BrowsingDataModel::StorageTypeSet>
diff --git a/components/cdm/renderer/key_system_support_update.cc b/components/cdm/renderer/key_system_support_update.cc
index 206c533..e48ac1a93 100644
--- a/components/cdm/renderer/key_system_support_update.cc
+++ b/components/cdm/renderer/key_system_support_update.cc
@@ -488,9 +488,10 @@
   key_systems->push_back(std::make_unique<ExternalClearKeyKeySystemInfo>(
       media::kMediaFoundationClearKeyKeySystem, std::vector<std::string>(),
       // MediaFoundation Clear Key Key System uses Windows Media Foundation's
-      // decoders and H264 is always supported. VideoCodec::kH264 is an
-      // EME_CODEC_AVC1.
-      media::EME_CODEC_AVC1,
+      // decoders. H264 ("avc1.64001E") for video and MP4 AAC ("mp4a.40.2") for
+      // audio are always supported. VideoCodec::kH264 is an EME_CODEC_AVC1.
+      // AudioCodec::kAAC is an EME_CODEC_AAC.
+      media::EME_CODEC_AVC1 | media::EME_CODEC_AAC,
       // On Windows, MediaFoundation Clear Key CDM requires identifier,
       // persistent state and HW secure codecs. We pretent to require these for
       // testing purposes.
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn
index 5fba7eb..8482d3b 100644
--- a/components/exo/BUILD.gn
+++ b/components/exo/BUILD.gn
@@ -307,6 +307,7 @@
     "//base/test:test_support",
     "//cc",
     "//cc:test_support",
+    "//chromeos/ash/components/login/auth",
     "//chromeos/dbus/power",
     "//chromeos/dbus/power:power_manager_proto",
     "//chromeos/ui/base",
diff --git a/components/exo/DEPS b/components/exo/DEPS
index 9612462..f58ece5 100644
--- a/components/exo/DEPS
+++ b/components/exo/DEPS
@@ -33,6 +33,7 @@
     "+components/viz/test",
   ],
   "ui_lock_controller_unittest\.cc": [
+    "+chromeos/ash/components/login/auth",
     "+chromeos/dbus/power",
     "+chromeos/dbus/power_manager",
   ],
diff --git a/components/exo/ui_lock_controller.cc b/components/exo/ui_lock_controller.cc
index fed387b..723e74a 100644
--- a/components/exo/ui_lock_controller.cc
+++ b/components/exo/ui_lock_controller.cc
@@ -217,6 +217,14 @@
     }
   }
 
+  // Notify again but this only notifies again the fullscreen notifier.
+  void NotifyAgainForFullscreen() {
+    ash::WindowState* window_state = ash::WindowState::Get(window_);
+    if (window_state->IsFullscreen()) {
+      OnFullscreen();
+    }
+  }
+
   void OnWindowDestroying(aura::Window* window) override {
     window_observation_.Reset();
     window_state_observation_.Reset();
@@ -578,11 +586,17 @@
 void UILockController::OnSurfaceFocused(Surface* gained_focus,
                                         Surface* lost_focus,
                                         bool has_focused_surface) {
-  if (gained_focus != focused_surface_to_unlock_)
+  if (gained_focus != focused_surface_to_unlock_) {
     StopTimer();
+  }
 
-  if (gained_focus)
-    GetExitNotifier(this, gained_focus->window(), true);
+  if (gained_focus) {
+    ExitNotifier* exit_notifier =
+        GetExitNotifier(this, gained_focus->window(), true);
+    if (exit_notifier) {
+      exit_notifier->NotifyAgainForFullscreen();
+    }
+  }
 }
 
 void UILockController::OnPointerCaptureEnabled(Pointer* pointer,
diff --git a/components/exo/ui_lock_controller_unittest.cc b/components/exo/ui_lock_controller_unittest.cc
index 7557d14..cee83d0 100644
--- a/components/exo/ui_lock_controller_unittest.cc
+++ b/components/exo/ui_lock_controller_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "base/test/power_monitor_test.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/ash/components/login/auth/auth_events_recorder.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/dbus/power_manager/backlight.pb.h"
@@ -138,6 +139,14 @@
   void SetUp() override {
     test::ExoTestBase::SetUp();
     seat_ = std::make_unique<Seat>();
+
+    // Order of window activations and observer callbacks is not trivial, e.g.
+    // lock screen widget is active when `OnLockStateChanged(locked=false)`
+    // callback is called. It's better to test them with views.
+    // `AuthEventsRecorder` is required for `set_show_lock_screen_views=true`.
+    auth_events_recorder_ = ash::AuthEventsRecorder::CreateForTesting();
+    GetSessionControllerClient()->set_show_lock_screen_views(true);
+
     WMHelper::GetInstance()->RegisterAppPropertyResolver(
         std::make_unique<TestPropertyResolver>());
   }
@@ -183,6 +192,7 @@
 
   std::unique_ptr<Seat> seat_;
   base::test::ScopedFeatureList scoped_feature_list_;
+  std::unique_ptr<ash::AuthEventsRecorder> auth_events_recorder_;
 };
 
 TEST_F(UILockControllerTest, HoldingEscapeExitsFullscreen) {
@@ -577,6 +587,9 @@
 }
 
 TEST_F(UILockControllerTest, PointerLockNotificationReshownOnUnlock) {
+  // Lock screen takes focus and it disables pointer capture.
+  GetSessionControllerClient()->set_show_lock_screen_views(false);
+
   // Arrange: Set up a pointer capture notification, then let it expire.
   std::unique_ptr<ShellSurface> test_surface = BuildSurface(1024, 768);
   test_surface->SetApplicationId(kOverviewToExitAppId);
diff --git a/components/optimization_guide/core/base_model_executor.h b/components/optimization_guide/core/base_model_executor.h
index 48f9416..eeabb86 100644
--- a/components/optimization_guide/core/base_model_executor.h
+++ b/components/optimization_guide/core/base_model_executor.h
@@ -15,16 +15,16 @@
 
 namespace optimization_guide {
 
-// An ModelExecutor that executes models with arbitrary
-// input and output types. Note that callers will need to give an implementation
-// of this class to a |ModelHandler|, whereas the
-// handle is the actual class that calling code would own and call into.
-template <class OutputType, class... InputTypes>
-class BaseModelExecutor : public TFLiteModelExecutor<OutputType, InputTypes...>,
-                          public InferenceDelegate<OutputType, InputTypes...> {
+// An ModelExecutor that executes models with arbitrary input and output types.
+// Note that callers will need to give an implementation of this class to a
+// |ModelHandler|, whereas the handle is the actual class that calling code
+// would own and call into.
+template <class OutputType, class InputType>
+class BaseModelExecutor : public TFLiteModelExecutor<OutputType, InputType>,
+                          public InferenceDelegate<OutputType, InputType> {
  public:
   using ModelExecutionTask =
-      tflite::task::core::BaseTaskApi<OutputType, InputTypes...>;
+      tflite::task::core::BaseTaskApi<OutputType, InputType>;
 
   BaseModelExecutor() = default;
   ~BaseModelExecutor() override = default;
@@ -40,7 +40,7 @@
       scoped_refptr<base::SequencedTaskRunner> reply_task_runner) override {
     num_threads_ = features::OverrideNumThreadsForOptTarget(optimization_target)
                        .value_or(-1);
-    TFLiteModelExecutor<OutputType, InputTypes...>::
+    TFLiteModelExecutor<OutputType, InputType>::
         InitializeAndMoveToExecutionThread(
             model_inference_timeout, optimization_target, execution_task_runner,
             reply_task_runner);
@@ -49,10 +49,10 @@
  protected:
   absl::optional<OutputType> Execute(ModelExecutionTask* execution_task,
                                      ExecutionStatus* out_status,
-                                     InputTypes... args) override {
-    return static_cast<GenericModelExecutionTask<OutputType, InputTypes...>*>(
+                                     InputType input) override {
+    return static_cast<GenericModelExecutionTask<OutputType, InputType>*>(
                execution_task)
-        ->Execute(out_status, args...);
+        ->Execute(out_status, input);
   }
 
   std::unique_ptr<ModelExecutionTask> BuildModelExecutionTask(
@@ -83,14 +83,13 @@
       return nullptr;
     }
 
-    return std::make_unique<
-        GenericModelExecutionTask<OutputType, InputTypes...>>(
+    return std::make_unique<GenericModelExecutionTask<OutputType, InputType>>(
         std::move(tflite_engine), this);
   }
 
   // InferenceDelegate:
   bool Preprocess(const std::vector<TfLiteTensor*>& input_tensors,
-                  InputTypes... input) override = 0;
+                  InputType input) override = 0;
   absl::optional<OutputType> Postprocess(
       const std::vector<const TfLiteTensor*>& output_tensors) override = 0;
 
diff --git a/components/optimization_guide/core/model_executor.h b/components/optimization_guide/core/model_executor.h
index fd5048c..f6cc0c88 100644
--- a/components/optimization_guide/core/model_executor.h
+++ b/components/optimization_guide/core/model_executor.h
@@ -62,6 +62,21 @@
                                 base::TimeTicks start_time,
                                 InputType input) = 0;
 
+  // Some callers define their InputType as a const ref type, but you can't make
+  // vectors of references. Strip those qualifiers off and add them back to the
+  // vector instead.
+  using ConstRefInputVector = const std::vector<typename std::remove_const<
+      typename std::remove_reference<InputType>::type>::type>&;
+
+  // It is guaranteed that the output passed to |BatchExecutionCallback| will
+  // always be in the same order as the input vector.
+  using BatchExecutionCallback =
+      base::OnceCallback<void(const std::vector<absl::optional<OutputType>>&)>;
+  virtual void SendForBatchExecution(
+      BatchExecutionCallback callback_on_complete,
+      base::TimeTicks start_time,
+      ConstRefInputVector inputs) = 0;
+
   // IMPORTANT: These WeakPointers must only be dereferenced on the
   // |execution_task_runner| thread.
   base::WeakPtr<ModelExecutor> GetWeakPtrForExecutionThread() {
diff --git a/components/optimization_guide/core/model_handler.h b/components/optimization_guide/core/model_handler.h
index 327dd88..0afe482 100644
--- a/components/optimization_guide/core/model_handler.h
+++ b/components/optimization_guide/core/model_handler.h
@@ -26,6 +26,19 @@
 
 namespace optimization_guide {
 
+namespace {
+
+void RecordTaskExecutionLatency(proto::OptimizationTarget optimization_target,
+                                base::TimeDelta execution_time) {
+  base::UmaHistogramMediumTimes(
+      "OptimizationGuide.ModelExecutor.TaskExecutionLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              optimization_target),
+      execution_time);
+}
+
+}  // namespace
+
 // This class owns and handles the execution of models on the UI thread.
 // Derived classes must provide an implementation of |ModelExecutor|
 // which is then owned by |this|. The passed executor will be called
@@ -108,6 +121,38 @@
                       GetExecutionTask(std::move(callback), input));
   }
 
+  // Variants of the above |ExecuteModelWithInput| but which support running
+  // multiple model executions in the same call stack. It is guaranteed that the
+  // output passed to |BatchExecutionCallback| will always be in the same order
+  // as the input vector.
+  //
+  // IMPORTANT: Running the model multiple times in the same PostTask means that
+  // it will take longer for Chrome's threadpool to reuse these CPU cycles for
+  // other work, especially for high priority tasks. This method should only be
+  // used in time-sensitive applications, for example when the model output is
+  // used on UI surfaces. Otherwise use multiple calls to
+  // |ExecuteModelWithInput| with a |base::BarrierClosure| (see
+  // page_content_annotation_job_executor.cc for an example and explanation).
+  using BatchExecutionCallback =
+      base::OnceCallback<void(const std::vector<absl::optional<OutputType>>&)>;
+  virtual void BatchExecuteModelWithInput(
+      BatchExecutionCallback callback,
+      ModelExecutor<OutputType, InputType>::ConstRefInputVector batch_input) {
+    model_executor_task_runner_->PostTask(
+        FROM_HERE, GetBatchExecutionTask(std::move(callback), batch_input));
+  }
+
+  // See above comment.
+  virtual void BatchExecuteModelWithInput(
+      base::CancelableTaskTracker* tracker,
+      BatchExecutionCallback callback,
+      ModelExecutor<OutputType, InputType>::ConstRefInputVector batch_input) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+    tracker->PostTask(model_executor_task_runner_.get(), FROM_HERE,
+                      GetBatchExecutionTask(std::move(callback), batch_input));
+  }
+
   void SetShouldUnloadModelOnComplete(bool should_auto_unload) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     model_executor_task_runner_->PostTask(
@@ -212,27 +257,46 @@
         std::move(on_complete_callback), now, input);
   }
 
+  // Returns a closure supplied with |callback| and |inputs| for model
+  // execution.
+  base::OnceClosure GetBatchExecutionTask(
+      BatchExecutionCallback callback,
+      ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs) {
+    base::TimeTicks now = base::TimeTicks::Now();
+
+    BatchExecutionCallback on_complete_callback =
+        base::BindOnce(&ModelHandler::OnBatchExecutionCompleted,
+                       std::move(callback), optimization_target_, now);
+    return base::BindOnce(
+        &ModelExecutor<OutputType, InputType>::SendForBatchExecution,
+        model_executor_->GetWeakPtrForExecutionThread(),
+        std::move(on_complete_callback), now, inputs);
+  }
+
   // This is called by |model_executor_|. This method does not have to be
   // static, but because it is stateless we've made it static so that we don't
-  // have to have this class support WeakPointers.
+  // have to have this class support WeakPointers on the calling thread.
   static void OnExecutionCompleted(
       ExecutionCallback callback,
       proto::OptimizationTarget optimization_target,
       base::TimeTicks model_execute_start_time,
       const absl::optional<OutputType>& output) {
-    if (!output) {
-      std::move(callback).Run(output);
-      return;
-    }
+    RecordTaskExecutionLatency(
+        optimization_target,
+        /*execution_time=*/base::TimeTicks::Now() - model_execute_start_time);
 
-    base::TimeDelta execution_time =
-        base::TimeTicks::Now() - model_execute_start_time;
+    std::move(callback).Run(output);
+  }
 
-    base::UmaHistogramMediumTimes(
-        "OptimizationGuide.ModelExecutor.TaskExecutionLatency." +
-            optimization_guide::GetStringNameForOptimizationTarget(
-                optimization_target),
-        execution_time);
+  static void OnBatchExecutionCompleted(
+      BatchExecutionCallback callback,
+      proto::OptimizationTarget optimization_target,
+      base::TimeTicks model_execute_start_time,
+      const std::vector<absl::optional<OutputType>>& output) {
+    RecordTaskExecutionLatency(
+        optimization_target,
+        /*execution_time=*/base::TimeTicks::Now() - model_execute_start_time);
+
     std::move(callback).Run(output);
   }
 
diff --git a/components/optimization_guide/core/test_model_executor.cc b/components/optimization_guide/core/test_model_executor.cc
index 91fa1e5e..9906dc6 100644
--- a/components/optimization_guide/core/test_model_executor.cc
+++ b/components/optimization_guide/core/test_model_executor.cc
@@ -6,13 +6,26 @@
 
 namespace optimization_guide {
 
-void TestModelExecutor::SendForExecution(
-    ExecutionCallback callback_on_complete,
-    base::TimeTicks start_time,
-    const std::vector<float>& args) {
-  std::vector<float> results = std::vector<float>();
-  for (auto& arg : args)
+void TestModelExecutor::SendForExecution(ExecutionCallback callback_on_complete,
+                                         base::TimeTicks start_time,
+                                         const std::vector<float>& args) {
+  std::vector<float> results;
+  results.reserve(args.size());
+  for (float arg : args) {
     results.push_back(arg);
+  }
+  std::move(callback_on_complete).Run(std::move(results));
+}
+
+void TestModelExecutor::SendForBatchExecution(
+    BatchExecutionCallback callback_on_complete,
+    base::TimeTicks start_time,
+    const std::vector<std::vector<float>>& args) {
+  std::vector<absl::optional<std::vector<float>>> results;
+  results.reserve(args.size());
+  for (const std::vector<float>& arg : args) {
+    results.push_back(arg);
+  }
   std::move(callback_on_complete).Run(std::move(results));
 }
 
diff --git a/components/optimization_guide/core/test_model_executor.h b/components/optimization_guide/core/test_model_executor.h
index ced168c..5c703a1 100644
--- a/components/optimization_guide/core/test_model_executor.h
+++ b/components/optimization_guide/core/test_model_executor.h
@@ -33,6 +33,13 @@
   void SendForExecution(ExecutionCallback callback_on_complete,
                         base::TimeTicks start_time,
                         const std::vector<float>& args) override;
+
+  using BatchExecutionCallback = base::OnceCallback<void(
+      const std::vector<absl::optional<std::vector<float>>>&)>;
+  void SendForBatchExecution(
+      BatchExecutionCallback callback_on_complete,
+      base::TimeTicks start_time,
+      const std::vector<std::vector<float>>& args) override;
 };
 
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/tflite_model_executor.h b/components/optimization_guide/core/tflite_model_executor.h
index f01619c6..c4f750f4 100644
--- a/components/optimization_guide/core/tflite_model_executor.h
+++ b/components/optimization_guide/core/tflite_model_executor.h
@@ -164,13 +164,33 @@
     model_fb_.reset();
   }
 
-  // Starts the execution of the model. When complete, |callback_on_complete|
-  // will be run via |reply_task_runner_| with the output of the model.
   using ExecutionCallback =
       base::OnceCallback<void(const absl::optional<OutputType>&)>;
+  using BatchExecutionCallback =
+      base::OnceCallback<void(const std::vector<absl::optional<OutputType>>&)>;
+
+  // When complete, |callback_on_complete| will be run via |reply_task_runner_|
+  // with the outputs of the model.
   void SendForExecution(ExecutionCallback callback_on_complete,
                         base::TimeTicks start_time,
                         InputType input) override {
+    BatchExecutionCallback adapted_callback = base::BindOnce(
+        [](ExecutionCallback callback,
+           const std::vector<absl::optional<OutputType>>& output) {
+          CHECK_EQ(output.size(), 1U);
+          std::move(callback).Run(output[0]);
+        },
+        std::move(callback_on_complete));
+    SendForBatchExecution(std::move(adapted_callback), start_time, {input});
+  }
+
+  // Starts the execution of the model. When complete, |callback_on_complete|
+  // will be run via |reply_task_runner_| with the outputs of the model.
+  void SendForBatchExecution(
+      BatchExecutionCallback callback_on_complete,
+      base::TimeTicks start_time,
+      ModelExecutor<OutputType, InputType>::ConstRefInputVector inputs)
+      override {
     DCHECK(execution_task_runner_->RunsTasksInCurrentSequence());
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     DCHECK(reply_task_runner_);
@@ -183,18 +203,31 @@
                 optimization_target_),
         task_scheduling_latency);
 
-    ScopedExecutionStatusResultRecorder status_recorder(optimization_target_);
+    std::vector<absl::optional<OutputType>> outputs;
+    outputs.reserve(inputs.size());
 
     // Attempt to load the model file if it isn't loaded yet, fail if loading is
     // unsuccessful or no model is available to load.
-    if (!loaded_model_ && !LoadModelFile(status_recorder.mutable_status())) {
-      reply_task_runner_->PostTask(
-          FROM_HERE,
-          base::BindOnce(std::move(callback_on_complete), absl::nullopt));
+    ExecutionStatus load_status = ExecutionStatus::kUnknown;
+    if (!loaded_model_ && !LoadModelFile(&load_status)) {
       // Some error status is expected, and derived classes should have set the
       // status.
-      DCHECK_NE(status_recorder.status(), ExecutionStatus::kUnknown);
-      DCHECK_NE(status_recorder.status(), ExecutionStatus::kSuccess);
+      DCHECK_NE(load_status, ExecutionStatus::kUnknown);
+      DCHECK_NE(load_status, ExecutionStatus::kSuccess);
+
+      for (size_t i = 0; i < inputs.size(); i++) {
+        outputs.push_back(absl::nullopt);
+        // If the model fails to load in a batch context, this status would not
+        // get recorded the same number of times as it would in success. Thus,
+        // increment the bucket |inputs.size()| number of times to keep metrics
+        // sane.
+        ScopedExecutionStatusResultRecorder status_recorder(
+            optimization_target_);
+        status_recorder.set_status(load_status);
+      }
+
+      reply_task_runner_->PostTask(
+          FROM_HERE, base::BindOnce(std::move(callback_on_complete), outputs));
       return;
     }
 
@@ -209,46 +242,49 @@
     last_execution_time_ = base::TimeTicks::Now();
 
     DCHECK(loaded_model_);
-    absl::optional<OutputType> output;
 
-    // IMPORTANT: Once the arm method is called, disarm must be called when the
-    // model execution finishes. Do NOT early-return in this next block.
-    if (watchdog_) {
-      watchdog_->ArmWithTask(loaded_model_.get());
-    }
-    {
-      TRACE_EVENT1("browser", "OptGuideModelExecutor::Execute",
-                   "OptimizationTarget",
-                   optimization_guide::GetStringNameForOptimizationTarget(
-                       optimization_target_));
-      base::ElapsedThreadTimer execution_timer;
-      base::TimeTicks execute_start_time = base::TimeTicks::Now();
-      output =
-          Execute(loaded_model_.get(), status_recorder.mutable_status(), input);
-      DCHECK_NE(status_recorder.status(), ExecutionStatus::kUnknown);
+    for (const InputType& input : inputs) {
+      ScopedExecutionStatusResultRecorder status_recorder(optimization_target_);
+      // IMPORTANT: Once the arm method is called, disarm must be called when
+      // the model execution finishes. Do NOT early-return in this next block.
+      if (watchdog_) {
+        watchdog_->ArmWithTask(loaded_model_.get());
+      }
+      {
+        TRACE_EVENT1("browser", "OptGuideModelExecutor::Execute",
+                     "OptimizationTarget",
+                     optimization_guide::GetStringNameForOptimizationTarget(
+                         optimization_target_));
+        base::ElapsedThreadTimer execution_timer;
+        base::TimeTicks execute_start_time = base::TimeTicks::Now();
+        absl::optional<OutputType> output = Execute(
+            loaded_model_.get(), status_recorder.mutable_status(), input);
+        DCHECK_NE(status_recorder.status(), ExecutionStatus::kUnknown);
+        outputs.push_back(output);
 
-      // The max of this histogram is 1 hour because we want to understand
-      // tail behavior and catch long running model executions.
-      base::UmaHistogramLongTimes(
-          "OptimizationGuide.ModelExecutor.ExecutionLatency." +
-              GetStringNameForOptimizationTarget(optimization_target_),
-          base::TimeTicks::Now() - execute_start_time);
-      base::UmaHistogramLongTimes(
-          "OptimizationGuide.ModelExecutor.ExecutionThreadTime." +
-              GetStringNameForOptimizationTarget(optimization_target_),
-          execution_timer.Elapsed());
-      base::UmaHistogramMicrosecondsTimes(
-          "OptimizationGuide.ModelExecutor.ExecutionThreadTimeMicroseconds." +
-              GetStringNameForOptimizationTarget(optimization_target_),
-          execution_timer.Elapsed());
-    }
-    if (watchdog_) {
-      watchdog_->DisarmOnExecutionComplete();
+        // The max of this histogram is 1 hour because we want to understand
+        // tail behavior and catch long running model executions.
+        base::UmaHistogramLongTimes(
+            "OptimizationGuide.ModelExecutor.ExecutionLatency." +
+                GetStringNameForOptimizationTarget(optimization_target_),
+            base::TimeTicks::Now() - execute_start_time);
+        base::UmaHistogramLongTimes(
+            "OptimizationGuide.ModelExecutor.ExecutionThreadTime." +
+                GetStringNameForOptimizationTarget(optimization_target_),
+            execution_timer.Elapsed());
+        base::UmaHistogramMicrosecondsTimes(
+            "OptimizationGuide.ModelExecutor.ExecutionThreadTimeMicroseconds." +
+                GetStringNameForOptimizationTarget(optimization_target_),
+            execution_timer.Elapsed());
+      }
+      if (watchdog_) {
+        watchdog_->DisarmOnExecutionComplete();
+      }
     }
 
     DCHECK(callback_on_complete);
     reply_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(std::move(callback_on_complete), output));
+        FROM_HERE, base::BindOnce(std::move(callback_on_complete), outputs));
 
     OnExecutionComplete();
   }
diff --git a/components/optimization_guide/core/tflite_model_executor_unittest.cc b/components/optimization_guide/core/tflite_model_executor_unittest.cc
index 69759a4..5113a6a 100644
--- a/components/optimization_guide/core/tflite_model_executor_unittest.cc
+++ b/components/optimization_guide/core/tflite_model_executor_unittest.cc
@@ -158,7 +158,7 @@
       "OptimizationGuide.ModelExecutor.TaskExecutionLatency." +
           optimization_guide::GetStringNameForOptimizationTarget(
               proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
-      0);
+      1);
   histogram_tester.ExpectTotalCount(
       "OptimizationGuide.ModelExecutor.TaskSchedulingLatency." +
           optimization_guide::GetStringNameForOptimizationTarget(
@@ -191,6 +191,67 @@
       ExecutionStatus::kErrorModelFileNotAvailable, 1);
 }
 
+TEST_F(TFLiteModelExecutorTest, BatchExecuteReturnsImmediatelyIfNoModelLoaded) {
+  base::HistogramTester histogram_tester;
+  CreateModelHandler();
+
+  base::RunLoop run_loop;
+  model_handler()->BatchExecuteModelWithInput(
+      base::BindOnce(
+          [](base::RunLoop* run_loop,
+             const std::vector<absl::optional<std::vector<float>>>& output) {
+            for (const auto& out : output) {
+              EXPECT_FALSE(out.has_value());
+            }
+            run_loop->Quit();
+          },
+          &run_loop),
+      {
+          std::vector<float>{0, 0, 0},
+          std::vector<float>{1, 1, 1},
+      });
+  run_loop.Run();
+
+  // Ensures pending tasks are processed. They are generating UMA metrics.
+  RunUntilIdle();
+
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.TaskExecutionLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.TaskSchedulingLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      0);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionThreadTime." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      0);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionThreadTimeMicroseconds." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      0);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ModelAvailableToLoad." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      false, 1);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ExecutionStatus." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      ExecutionStatus::kErrorModelFileNotAvailable, 2);
+}
+
 TEST_F(TFLiteModelExecutorTest, ExecuteWithLoadedModel) {
   base::HistogramTester histogram_tester;
   CreateModelHandler();
@@ -270,6 +331,82 @@
       true, 1);
 }
 
+TEST_F(TFLiteModelExecutorTest, BatchExecuteWithLoadedModel) {
+  base::HistogramTester histogram_tester;
+  CreateModelHandler();
+
+  PushModelFileToModelExecutor(
+      proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD,
+      /*model_metadata=*/absl::nullopt);
+  EXPECT_TRUE(model_handler()->ModelAvailable());
+
+  std::vector<float> input;
+  int expected_dims = 1 * 32 * 32 * 3;
+  input.reserve(expected_dims);
+  for (int i = 0; i < expected_dims; i++) {
+    input.emplace_back(1);
+  }
+
+  base::RunLoop run_loop;
+  model_handler()->BatchExecuteModelWithInput(
+      base::BindOnce(
+          [](base::RunLoop* run_loop,
+             const std::vector<absl::optional<std::vector<float>>>& output) {
+            for (const auto& out : output) {
+              EXPECT_TRUE(out.has_value());
+            }
+
+            run_loop->Quit();
+          },
+          &run_loop),
+      {input, input});
+  run_loop.Run();
+
+  // Ensures pending tasks are processed. They are generating UMA metrics.
+  RunUntilIdle();
+
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.TaskExecutionLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.TaskSchedulingLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionLatency." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      2);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionThreadTime." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      2);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelExecutor.ExecutionThreadTimeMicroseconds." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      2);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ModelAvailableToLoad." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      true, 1);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ExecutionStatus." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      ExecutionStatus::kSuccess, 2);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ModelLoadedSuccessfully." +
+          optimization_guide::GetStringNameForOptimizationTarget(
+              proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD),
+      true, 1);
+}
+
 TEST_F(TFLiteModelExecutorTest, ExecuteTwiceWithLoadedModel) {
   base::HistogramTester histogram_tester;
   CreateModelHandler();
@@ -539,6 +676,47 @@
       "OptimizationGuide.ModelExecutor.DidTimeout.PainfulPageLoad", true, 1);
 }
 
+TEST_F(CancelledTFLiteModelExecutorTest, BatchRunsTooLong) {
+  base::HistogramTester histogram_tester;
+  CreateModelHandler();
+
+  PushModelFileToModelExecutor(
+      proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD,
+      /*model_metadata=*/absl::nullopt);
+  EXPECT_TRUE(model_handler()->ModelAvailable());
+
+  std::vector<float> input;
+  size_t expected_dims = 1 * 32 * 32 * 3;
+  input.reserve(expected_dims);
+  for (size_t i = 0; i < expected_dims; i++) {
+    input.emplace_back(1);
+  }
+
+  base::RunLoop run_loop;
+  model_handler()->BatchExecuteModelWithInput(
+      base::BindOnce(
+          [](base::RunLoop* run_loop,
+             const std::vector<absl::optional<std::vector<float>>>& output) {
+            for (const auto& out : output) {
+              EXPECT_FALSE(out.has_value());
+            }
+            run_loop->Quit();
+          },
+          &run_loop),
+      {input, input});
+  run_loop.Run();
+
+  // Ensures pending tasks are processed. They are generating UMA metrics.
+  RunUntilIdle();
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.ExecutionStatus.PainfulPageLoad",
+      ExecutionStatus::kErrorCancelled, 2);
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelExecutor.DidTimeout.PainfulPageLoad", true, 2);
+}
+
 TEST_F(TFLiteModelExecutorTest, UpdateModelFileWithPreloading) {
   base::HistogramTester histogram_tester;
   CreateModelHandler();
diff --git a/components/password_manager/ios/shared_password_controller.h b/components/password_manager/ios/shared_password_controller.h
index e16a090..23d874e2 100644
--- a/components/password_manager/ios/shared_password_controller.h
+++ b/components/password_manager/ios/shared_password_controller.h
@@ -19,6 +19,9 @@
 #import "ios/web/public/js_messaging/web_frames_manager_observer_bridge.h"
 #import "ios/web/public/web_state_observer_bridge.h"
 
+// The string ' ••••••••' appended to the username in the suggestion.
+extern NSString* const kPasswordFormSuggestionSuffix;
+
 namespace password_manager {
 class PasswordManagerClient;
 }  // namespace password_manager
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm
index a944ca5..847b8b2 100644
--- a/components/password_manager/ios/shared_password_controller.mm
+++ b/components/password_manager/ios/shared_password_controller.mm
@@ -91,11 +91,10 @@
 // Password is considered not generated when user edits it below 4 characters.
 constexpr int kMinimumLengthForEditedPassword = 4;
 
-// The string ' •••' appended to the username in the suggestion.
-NSString* const kSuggestionSuffix = @" ••••••••";
-
 }  // namespace
 
+NSString* const kPasswordFormSuggestionSuffix = @" ••••••••";
+
 @interface SharedPasswordController ()
 
 // Helper contains common password suggestion logic.
@@ -460,8 +459,8 @@
       continue;
     }
     DCHECK(self.delegate.passwordManagerClient);
-    NSString* value =
-        [rawSuggestion.value stringByAppendingString:kSuggestionSuffix];
+    NSString* value = [rawSuggestion.value
+        stringByAppendingString:kPasswordFormSuggestionSuffix];
     FormSuggestion* suggestion =
         [FormSuggestion suggestionWithValue:value
                          displayDescription:rawSuggestion.displayDescription
@@ -559,9 +558,10 @@
           password_manager::metrics_util::PasswordDropdownSelectedOption::
               kPassword,
           [self IsOffTheRecord]);
-      DCHECK([suggestion.value hasSuffix:kSuggestionSuffix]);
+      DCHECK([suggestion.value hasSuffix:kPasswordFormSuggestionSuffix]);
       NSString* username = [suggestion.value
-          substringToIndex:suggestion.value.length - kSuggestionSuffix.length];
+          substringToIndex:suggestion.value.length -
+                           kPasswordFormSuggestionSuffix.length];
       std::unique_ptr<password_manager::FillData> fillData =
           [self.suggestionHelper passwordFillDataForUsername:username
                                                      inFrame:frame];
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc
index 785c92e..e8b91e7 100644
--- a/components/performance_manager/features.cc
+++ b/components/performance_manager/features.cc
@@ -112,10 +112,17 @@
     &kMemorySavingsReportingImprovements,
     "high_efficiency_chart_pmf_75_percentile_bytes", 197 * 1024 * 1024};
 
-const base::FeatureParam<int> kDiscardedTabTreatmenOption{
+const base::FeatureParam<double> kDiscardedTabTreatmentOpacity{
+    &kDiscardedTabTreatment, "discard_tab_treatment_opacity", 0.3};
+
+const base::FeatureParam<int> kDiscardedTabTreatmentOption{
     &kDiscardedTabTreatment, "discard_tab_treatment_option",
     static_cast<int>(DiscardTabTreatmentOptions::kFadeFullsizedFavicon)};
 
+BASE_FEATURE(kUseDeviceBatterySaverChromeOS,
+             "UseDeviceBatterySaverChromeOS",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 #endif
 
 BASE_FEATURE(kBFCachePerformanceManagerPolicy,
diff --git a/components/performance_manager/public/features.h b/components/performance_manager/public/features.h
index 8976160..fa9efb8 100644
--- a/components/performance_manager/public/features.h
+++ b/components/performance_manager/public/features.h
@@ -133,7 +133,13 @@
 extern const base::FeatureParam<int> kHighEfficiencyChartPmf50PercentileBytes;
 extern const base::FeatureParam<int> kHighEfficiencyChartPmf75PercentileBytes;
 
-extern const base::FeatureParam<int> kDiscardedTabTreatmenOption;
+// Final opacity of the favicon after the discard animation completes
+extern const base::FeatureParam<double> kDiscardedTabTreatmentOpacity;
+
+// The version of the tab discard treatment on the favicon should be shown
+extern const base::FeatureParam<int> kDiscardedTabTreatmentOption;
+
+BASE_DECLARE_FEATURE(kUseDeviceBatterySaverChromeOS);
 
 enum class DiscardTabTreatmentOptions {
   kNone = 0,
diff --git a/components/policy/core/common/cloud/dm_token.cc b/components/policy/core/common/cloud/dm_token.cc
index f3a3e71..3c23309 100644
--- a/components/policy/core/common/cloud/dm_token.cc
+++ b/components/policy/core/common/cloud/dm_token.cc
@@ -23,21 +23,6 @@
   return DMToken(Status::kEmpty, "");
 }
 
-// static
-DMToken DMToken::CreateValidTokenForTesting(const std::string& value) {
-  return CreateValidToken(value);
-}
-
-// static
-DMToken DMToken::CreateInvalidTokenForTesting() {
-  return CreateInvalidToken();
-}
-
-// static
-DMToken DMToken::CreateEmptyTokenForTesting() {
-  return CreateEmptyToken();
-}
-
 DMToken::DMToken(Status status, const base::StringPiece value)
     : status_(status), value_(value) {}
 
diff --git a/components/policy/core/common/cloud/dm_token.h b/components/policy/core/common/cloud/dm_token.h
index a24594ff..457dc589 100644
--- a/components/policy/core/common/cloud/dm_token.h
+++ b/components/policy/core/common/cloud/dm_token.h
@@ -29,11 +29,6 @@
   static DMToken CreateInvalidToken();
   static DMToken CreateEmptyToken();
 
-  // Deprecated, use the non-testing factory functions instead.
-  static DMToken CreateValidTokenForTesting(const std::string& value);
-  static DMToken CreateInvalidTokenForTesting();
-  static DMToken CreateEmptyTokenForTesting();
-
   DMToken(const DMToken& other) = default;
   DMToken(DMToken&& other) = default;
 
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc
index 27c22b90..cf0390b 100644
--- a/components/policy/core/common/features.cc
+++ b/components/policy/core/common/features.cc
@@ -39,7 +39,7 @@
 #if BUILDFLAG(IS_IOS)
 BASE_FEATURE(kPolicyLogsPageIOS,
              "PolicyLogsPageIOS",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif  // BUILDFLAG(IS_IOS)
 
 }  // namespace features
diff --git a/components/reading_list/features/reading_list_switches.cc b/components/reading_list/features/reading_list_switches.cc
index 81de250..de91c0c 100644
--- a/components/reading_list/features/reading_list_switches.cc
+++ b/components/reading_list/features/reading_list_switches.cc
@@ -16,13 +16,6 @@
              "ReadLaterBackendMigration",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-#if BUILDFLAG(IS_ANDROID)
-// Feature flag used for enabling read later reminder notification.
-BASE_FEATURE(kReadLaterReminderNotification,
-             "ReadLaterReminderNotification",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-#endif
-
 BASE_FEATURE(kReadingListEnableDualReadingListModel,
              "ReadingListEnableDualReadingListModel",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/reading_list/features/reading_list_switches.h b/components/reading_list/features/reading_list_switches.h
index 98e6d6d..8e7c849 100644
--- a/components/reading_list/features/reading_list_switches.h
+++ b/components/reading_list/features/reading_list_switches.h
@@ -20,11 +20,6 @@
 // details.
 BASE_DECLARE_FEATURE(kReadLaterBackendMigration);
 
-#if BUILDFLAG(IS_ANDROID)
-// Feature flag used for enabling read later reminder notification.
-BASE_DECLARE_FEATURE(kReadLaterReminderNotification);
-#endif
-
 // Feature flag that controls a technical rollout of a new codepath that doesn't
 // itself cause user-facing changes but sets the foundation for later rollouts
 // namely, `kReadingListEnableSyncTransportModeUponSignIn` below).
diff --git a/components/reporting/metrics/fakes/fake_reporting_settings.cc b/components/reporting/metrics/fakes/fake_reporting_settings.cc
index e7b5053..39d6e41 100644
--- a/components/reporting/metrics/fakes/fake_reporting_settings.cc
+++ b/components/reporting/metrics/fakes/fake_reporting_settings.cc
@@ -59,6 +59,15 @@
   return true;
 }
 
+bool FakeReportingSettings::GetReportingEnabled(const std::string& path,
+                                                bool* out_value) const {
+  if (!base::Contains(reporting_enabled_map_, path)) {
+    return false;
+  }
+  *out_value = reporting_enabled_map_.at(path);
+  return true;
+}
+
 void FakeReportingSettings::SetBoolean(const std::string& path,
                                        bool bool_value) {
   bool_map_[path] = bool_value;
@@ -83,6 +92,14 @@
   }
 }
 
+void FakeReportingSettings::SetReportingEnabled(const std::string& path,
+                                                bool enabled_value) {
+  reporting_enabled_map_[path] = enabled_value;
+  if (base::Contains(settings_callbacks_map_, path)) {
+    settings_callbacks_map_.at(path)->Notify();
+  }
+}
+
 void FakeReportingSettings::SetIsTrusted(bool is_trusted) {
   base::RunLoop run_loop;
   is_trusted_ = is_trusted;
diff --git a/components/reporting/metrics/fakes/fake_reporting_settings.h b/components/reporting/metrics/fakes/fake_reporting_settings.h
index 7bfb337d..8175828f 100644
--- a/components/reporting/metrics/fakes/fake_reporting_settings.h
+++ b/components/reporting/metrics/fakes/fake_reporting_settings.h
@@ -37,6 +37,8 @@
   bool GetInteger(const std::string& path, int* out_value) const override;
   bool GetList(const std::string& path,
                const base::Value::List** out_value) const override;
+  bool GetReportingEnabled(const std::string& path,
+                           bool* out_value) const override;
 
   void SetBoolean(const std::string& path, bool bool_value);
 
@@ -44,6 +46,8 @@
 
   void SetList(const std::string& path, const base::Value::List& list_value);
 
+  void SetReportingEnabled(const std::string& path, bool enabled_value);
+
   void SetIsTrusted(bool is_trusted);
 
  private:
@@ -55,6 +59,7 @@
   base::flat_map<std::string, bool> bool_map_;
   base::flat_map<std::string, int> int_map_;
   base::flat_map<std::string, base::Value::List> list_map_;
+  base::flat_map<std::string, bool> reporting_enabled_map_;
 
   bool is_trusted_ = true;
 };
diff --git a/components/reporting/metrics/manual_collector_unittest.cc b/components/reporting/metrics/manual_collector_unittest.cc
index 372b1ca..c79f586 100644
--- a/components/reporting/metrics/manual_collector_unittest.cc
+++ b/components/reporting/metrics/manual_collector_unittest.cc
@@ -57,7 +57,7 @@
 
 TEST_F(ManualCollectorTest, InitiallyEnabled) {
   // Initially enable settings
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   MetricData metric_data = GetMetricData();
   sampler_->SetMetricData(std::move(metric_data));
 
@@ -82,7 +82,7 @@
 
 TEST_F(ManualCollectorTest, InitiallyDisabled) {
   // Initially disable settings
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
 
   MetricData metric_data = GetMetricData();
 
@@ -102,7 +102,7 @@
   EXPECT_TRUE(metric_report_queue_->IsEmpty());
 
   // Enable settings
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   collector.Collect(is_event_driven);
 
@@ -116,7 +116,7 @@
 }
 
 TEST_F(ManualCollectorTest, NoMetricData) {
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   sampler_->SetMetricData(absl::nullopt);
 
diff --git a/components/reporting/metrics/metric_event_observer_manager_unittest.cc b/components/reporting/metrics/metric_event_observer_manager_unittest.cc
index 993e520..5cb08d3 100644
--- a/components/reporting/metrics/metric_event_observer_manager_unittest.cc
+++ b/components/reporting/metrics/metric_event_observer_manager_unittest.cc
@@ -72,7 +72,7 @@
 };
 
 TEST_F(MetricEventObserverManagerTest, InitiallyEnabled) {
-  settings_->SetBoolean(kEventEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, true);
   auto* event_observer_ptr = event_observer_.get();
 
   MetricEventObserverManager event_manager(
@@ -96,7 +96,7 @@
 
   // Setting disabled, no more data should be reported even if the callback is
   // called.
-  settings_->SetBoolean(kEventEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, false);
 
   event_observer_ptr->RunCallback(metric_data);
 
@@ -105,7 +105,7 @@
 }
 
 TEST_F(MetricEventObserverManagerTest, InitiallyEnabled_Delayed) {
-  settings_->SetBoolean(kEventEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, true);
   auto* event_observer_ptr = event_observer_.get();
 
   MetricEventObserverManager event_manager(
@@ -134,7 +134,7 @@
 
   // Setting disabled, no more data should be reported even if the callback is
   // called.
-  settings_->SetBoolean(kEventEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, false);
 
   event_observer_ptr->RunCallback(metric_data);
 
@@ -143,7 +143,7 @@
 }
 
 TEST_F(MetricEventObserverManagerTest, InitiallyDisabled_Delayed) {
-  settings_->SetBoolean(kEventEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, false);
   auto* event_observer_ptr = event_observer_.get();
 
   MetricEventObserverManager event_manager(
@@ -159,7 +159,7 @@
   event_observer_ptr->RunCallback(metric_data);
   ASSERT_TRUE(metric_report_queue_->IsEmpty());
 
-  settings_->SetBoolean(kEventEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, true);
 
   task_environment_.FastForwardBy(init_delay / 2);
 
@@ -178,7 +178,7 @@
 }
 
 TEST_F(MetricEventObserverManagerTest, InitiallyDisabled) {
-  settings_->SetBoolean(kEventEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, false);
   auto* event_observer_ptr = event_observer_.get();
 
   MetricEventObserverManager event_manager(
@@ -194,7 +194,7 @@
   ASSERT_FALSE(event_observer_ptr->GetReportingEnabled());
   EXPECT_TRUE(metric_report_queue_->IsEmpty());
 
-  settings_->SetBoolean(kEventEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, true);
 
   event_observer_ptr->RunCallback(metric_data);
 
@@ -244,7 +244,7 @@
 }
 
 TEST_F(MetricEventObserverManagerTest, EventDrivenTelemetry) {
-  settings_->SetBoolean(kEventEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEventEnableSettingPath, true);
   auto* event_observer_ptr = event_observer_.get();
   MetricEventType network_event = MetricEventType::WIFI_SIGNAL_STRENGTH_LOW;
 
diff --git a/components/reporting/metrics/metric_reporting_controller.cc b/components/reporting/metrics/metric_reporting_controller.cc
index fc9963b..5ee07fc4 100644
--- a/components/reporting/metrics/metric_reporting_controller.cc
+++ b/components/reporting/metrics/metric_reporting_controller.cc
@@ -62,7 +62,7 @@
   }
 
   bool new_setting_enabled = setting_enabled_default_value_;
-  reporting_settings_->GetBoolean(setting_path_, &new_setting_enabled);
+  reporting_settings_->GetReportingEnabled(setting_path_, &new_setting_enabled);
 
   if (setting_enabled_ != new_setting_enabled) {
     setting_enabled_ = new_setting_enabled;
diff --git a/components/reporting/metrics/metric_reporting_controller_unittest.cc b/components/reporting/metrics/metric_reporting_controller_unittest.cc
index 0710254..c5c1894 100644
--- a/components/reporting/metrics/metric_reporting_controller_unittest.cc
+++ b/components/reporting/metrics/metric_reporting_controller_unittest.cc
@@ -57,7 +57,7 @@
 }
 
 TEST_F(MetricReportingControllerTest, TrustedCheck) {
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
   settings_->SetIsTrusted(false);
 
   MetricReportingController controller(settings_.get(), kSettingPath,
@@ -74,7 +74,7 @@
 }
 
 TEST_F(MetricReportingControllerTest, InitiallyEnabled) {
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   MetricReportingController controller(settings_.get(), kSettingPath,
                                        /*setting_enabled_default_value=*/false);
@@ -85,14 +85,14 @@
   EXPECT_EQ(disable_count_, 0);
 
   // Change to disable.
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   // Only disable_cb_ is called.
   EXPECT_EQ(enable_count_, 1);
   EXPECT_EQ(disable_count_, 1);
 
   // Change to enable.
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   // Only enable_cb_ is called.
   EXPECT_EQ(enable_count_, 2);
@@ -100,7 +100,7 @@
 }
 
 TEST_F(MetricReportingControllerTest, InitiallyDisabled) {
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   MetricReportingController controller(settings_.get(), kSettingPath,
                                        /*setting_enabled_default_value=*/false);
@@ -111,14 +111,14 @@
   EXPECT_EQ(disable_count_, 0);
 
   // Change to enable.
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   // Only enable_cb_ is called.
   EXPECT_EQ(enable_count_, 1);
   EXPECT_EQ(disable_count_, 0);
 
   // Change to disable.
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   // Only disable_cb_ is called.
   EXPECT_EQ(enable_count_, 1);
@@ -126,13 +126,13 @@
 }
 
 TEST_F(MetricReportingControllerTest, SetCallbackAfterEnable) {
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   MetricReportingController controller(settings_.get(), kSettingPath,
                                        /*setting_enabled_default_value=*/false);
 
   // Change to enable.
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   controller.SetSettingUpdateCb(std::move(enable_cb_), std::move(disable_cb_));
 
@@ -141,7 +141,7 @@
   EXPECT_EQ(disable_count_, 0);
 
   // Change to disable.
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   // Only disable_cb_ is called.
   EXPECT_EQ(enable_count_, 1);
@@ -149,13 +149,13 @@
 }
 
 TEST_F(MetricReportingControllerTest, SetCallbackAfterDisable) {
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   MetricReportingController controller(settings_.get(), kSettingPath,
                                        /*setting_enabled_default_value=*/false);
 
   // Change to disable.
-  settings_->SetBoolean(kSettingPath, false);
+  settings_->SetReportingEnabled(kSettingPath, false);
 
   controller.SetSettingUpdateCb(std::move(enable_cb_), std::move(disable_cb_));
 
@@ -164,7 +164,7 @@
   EXPECT_EQ(disable_count_, 0);
 
   // Change to enable.
-  settings_->SetBoolean(kSettingPath, true);
+  settings_->SetReportingEnabled(kSettingPath, true);
 
   // Only enable_cb_ is called.
   EXPECT_EQ(enable_count_, 1);
diff --git a/components/reporting/metrics/one_shot_collector_unittest.cc b/components/reporting/metrics/one_shot_collector_unittest.cc
index 9afb0a9..48e2484 100644
--- a/components/reporting/metrics/one_shot_collector_unittest.cc
+++ b/components/reporting/metrics/one_shot_collector_unittest.cc
@@ -46,7 +46,7 @@
 };
 
 TEST_F(OneShotCollectorTest, InitiallyEnabled) {
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   MetricData metric_data;
   metric_data.mutable_telemetry_data();
@@ -61,8 +61,8 @@
   // Setting is initially enabled, data is being collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(1));
 
-  settings_->SetBoolean(kEnableSettingPath, false);
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // No more data should be collected even if the setting was disabled then
   // re-enabled.
@@ -77,13 +77,13 @@
   EXPECT_FALSE(metric_data_reported.telemetry_data().has_is_event_driven());
   EXPECT_TRUE(metric_report_queue_->IsEmpty());
 
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
   collector.Collect(/*is_event_driven=*/true);
 
   // No new data collection, setting is disabled.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(1));
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   collector.Collect(/*is_event_driven=*/true);
 
   // Number of collection calls increased by one, setting is enabled and manual
@@ -100,7 +100,7 @@
 
 TEST_F(OneShotCollectorTest, InitiallyEnabled_Delayed) {
   constexpr base::TimeDelta init_delay = base::Minutes(2);
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   MetricData metric_data;
   metric_data.mutable_telemetry_data();
@@ -136,8 +136,8 @@
   // Setting is initially enabled and `init_delay` elapsed, data is collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(2));
 
-  settings_->SetBoolean(kEnableSettingPath, false);
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // No more data should be collected even if the setting was disabled then
   // re-enabled.
@@ -152,7 +152,7 @@
 }
 
 TEST_F(OneShotCollectorTest, NoMetricData) {
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   sampler_->SetMetricData(absl::nullopt);
 
@@ -169,7 +169,7 @@
 }
 
 TEST_F(OneShotCollectorTest, InitiallyDisabled) {
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
 
   MetricData metric_data;
   metric_data.mutable_info_data();
@@ -182,13 +182,13 @@
   // Setting is initially disabled, no data is collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(0));
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // Setting is enabled, data is being collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(1));
 
-  settings_->SetBoolean(kEnableSettingPath, false);
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // No more data should be collected even if the setting was disabled then
   // re-enabled.
@@ -204,7 +204,7 @@
 
 TEST_F(OneShotCollectorTest, InitiallyDisabled_Delayed) {
   constexpr base::TimeDelta init_delay = base::Minutes(1);
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
 
   MetricData metric_data;
   metric_data.mutable_info_data();
@@ -220,13 +220,13 @@
   // Setting is initially disabled, no data is collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(0));
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // Setting is enabled, data is being collected.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(1));
 
-  settings_->SetBoolean(kEnableSettingPath, false);
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
 
   // No more data should be collected even if the setting was disabled then
   // re-enabled.
diff --git a/components/reporting/metrics/periodic_collector_unittest.cc b/components/reporting/metrics/periodic_collector_unittest.cc
index ab2e959..49da392 100644
--- a/components/reporting/metrics/periodic_collector_unittest.cc
+++ b/components/reporting/metrics/periodic_collector_unittest.cc
@@ -47,7 +47,7 @@
 };
 
 TEST_F(PeriodicCollectorTest, InitiallyEnabled) {
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   settings_->SetInteger(kRateSettingPath, interval.InMilliseconds());
 
   MetricData metric_data_list[5];
@@ -84,12 +84,12 @@
   }
 
   sampler_->SetMetricData(metric_data_list[3]);
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
   // Setting disabled, no data should be collected.
   task_environment_.FastForwardBy(interval);
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(expected_collect_calls));
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   // Initial collection at policy enablement.
   ++expected_collect_calls;
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(expected_collect_calls));
@@ -120,7 +120,7 @@
 TEST_F(PeriodicCollectorTest, InitiallyEnabled_Delayed) {
   constexpr base::TimeDelta init_delay = base::Minutes(1);
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   settings_->SetInteger(kRateSettingPath, interval.InMilliseconds());
 
   MetricData metric_data;
@@ -169,7 +169,7 @@
 }
 
 TEST_F(PeriodicCollectorTest, NoMetricData) {
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   settings_->SetInteger(kRateSettingPath, interval.InMilliseconds());
 
   sampler_->SetMetricData(absl::nullopt);
@@ -187,7 +187,7 @@
 }
 
 TEST_F(PeriodicCollectorTest, InitiallyDisabled) {
-  settings_->SetBoolean(kEnableSettingPath, false);
+  settings_->SetReportingEnabled(kEnableSettingPath, false);
   settings_->SetInteger(kRateSettingPath, interval.InMilliseconds());
 
   MetricData metric_data;
@@ -209,7 +209,7 @@
   // Manual collection is triggered but reporting is disabled.
   EXPECT_EQ(sampler_->GetNumCollectCalls(), 0);
 
-  settings_->SetBoolean(kEnableSettingPath, true);
+  settings_->SetReportingEnabled(kEnableSettingPath, true);
   // One initial collection at policy enablement.
   EXPECT_THAT(sampler_->GetNumCollectCalls(), Eq(1));
 
diff --git a/components/reporting/metrics/reporting_settings.h b/components/reporting/metrics/reporting_settings.h
index 717ec83..6aabc0b 100644
--- a/components/reporting/metrics/reporting_settings.h
+++ b/components/reporting/metrics/reporting_settings.h
@@ -35,6 +35,11 @@
   virtual bool GetInteger(const std::string& path, int* out_value) const = 0;
   virtual bool GetList(const std::string& path,
                        const base::Value::List** out_value) const = 0;
+
+  // Return whether reporting is enabled or not, allowed settings types will be
+  // defined by the implementation.
+  virtual bool GetReportingEnabled(const std::string& path,
+                                   bool* out_value) const = 0;
 };
 
 }  // namespace reporting
diff --git a/components/saved_tab_groups/saved_tab_group_model.cc b/components/saved_tab_groups/saved_tab_group_model.cc
index c1d900cc..9a911616 100644
--- a/components/saved_tab_groups/saved_tab_group_model.cc
+++ b/components/saved_tab_groups/saved_tab_group_model.cc
@@ -259,7 +259,11 @@
 
   // Remove the group from the model if the last tab will be removed from it.
   if (group.saved_tabs().size() == 1) {
-    Remove(group_id);
+    if (update_tab_positions) {
+      Remove(group_id);
+    } else {
+      RemovedFromSync(group_id);
+    }
     return;
   }
 
diff --git a/components/saved_tab_groups/saved_tab_group_sync_bridge.cc b/components/saved_tab_groups/saved_tab_group_sync_bridge.cc
index 591fc7a..cda9e3d9 100644
--- a/components/saved_tab_groups/saved_tab_group_sync_bridge.cc
+++ b/components/saved_tab_groups/saved_tab_group_sync_bridge.cc
@@ -374,7 +374,7 @@
   // Check if the model contains the group guid. If so, remove that group and
   // all of its tabs.
   if (model_->Contains(guid)) {
-    model_->Remove(guid);
+    model_->RemovedFromSync(guid);
     return;
   }
 
diff --git a/components/site_isolation/site_isolation_policy_unittest.cc b/components/site_isolation/site_isolation_policy_unittest.cc
index 0db7c3e..dab88de4 100644
--- a/components/site_isolation/site_isolation_policy_unittest.cc
+++ b/components/site_isolation/site_isolation_policy_unittest.cc
@@ -75,6 +75,14 @@
     content::SetBrowserClientForTesting(original_client_);
   }
 
+  void SetUp() override {
+    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
+  }
+
+  void TearDown() override {
+    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
+  }
+
  protected:
   void SetEnableStrictSiteIsolation(bool enable) {
     browser_client_.strict_isolation_enabled_ = enable;
@@ -524,6 +532,7 @@
     // On Android official builds, we expect to isolate an additional set of
     // built-in origins.
     expected_embedder_origins_ = GetBrowserSpecificBuiltInIsolatedOrigins();
+    BaseSiteIsolationTest::SetUp();
   }
 
  protected:
@@ -727,11 +736,7 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableLowEndDeviceMode);
     EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
-  }
-
-  void TearDown() override {
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
+    BaseSiteIsolationTest::SetUp();
   }
 
  protected:
@@ -944,11 +949,7 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableLowEndDeviceMode);
     EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
-  }
-
-  void TearDown() override {
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
+    BaseSiteIsolationTest::SetUp();
   }
 
  protected:
@@ -1074,6 +1075,7 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kEnableLowEndDeviceMode);
     EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
+    SiteIsolationPolicyTest::SetUp();
   }
 };
 
@@ -1205,15 +1207,9 @@
     SetEnableStrictSiteIsolation(false);
     // Enable Origin-Agent-Cluster header.
     feature_list_.InitAndEnableFeature(::features::kOriginIsolationHeader);
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
     BaseSiteIsolationTest::SetUp();
   }
 
-  void TearDown() override {
-    SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
-    BaseSiteIsolationTest::TearDown();
-  }
-
   content::BrowserContext* browser_context() { return &browser_context_; }
 
  private:
diff --git a/components/supervised_user/core/browser/BUILD.gn b/components/supervised_user/core/browser/BUILD.gn
index 86484974..bafbcf4 100644
--- a/components/supervised_user/core/browser/BUILD.gn
+++ b/components/supervised_user/core/browser/BUILD.gn
@@ -6,14 +6,31 @@
   import("//build/config/android/rules.gni")
 }
 
-static_library("browser") {
+static_library("fetcher") {
   sources = [
     "kids_access_token_fetcher.cc",
     "kids_access_token_fetcher.h",
-    "kids_chrome_management_client.cc",
-    "kids_chrome_management_client.h",
     "kids_external_fetcher.cc",
     "kids_external_fetcher.h",
+    "kids_external_fetcher_config.cc",
+    "kids_external_fetcher_config.h",
+    "kids_external_fetcher_requests.h",
+  ]
+  deps = [
+    "//base",
+    "//components/signin/public/identity_manager",
+    "//components/supervised_user/core/browser/proto",
+    "//components/supervised_user/core/common",
+    "//google_apis",
+    "//net/traffic_annotation",
+    "//url",
+  ]
+}
+
+static_library("browser") {
+  sources = [
+    "kids_chrome_management_client.cc",
+    "kids_chrome_management_client.h",
     "kids_management_url_checker_client.cc",
     "kids_management_url_checker_client.h",
     "parental_control_metrics.cc",
@@ -50,6 +67,7 @@
   ]
 
   deps = [
+    ":fetcher",
     "//base",
     "//components/feed/core/shared_prefs:feed_shared_prefs",
     "//components/google/core/common",
@@ -70,6 +88,20 @@
   ]
 }
 
+source_set("test_support") {
+  testonly = true
+  sources = [
+    "fetcher_config_test_utils.cc",
+    "fetcher_config_test_utils.h",
+  ]
+  deps = [
+    ":fetcher",
+    "//base",
+    "//net/traffic_annotation",
+    "//url",
+  ]
+}
+
 source_set("unit_tests") {
   testonly = true
   sources = [
@@ -88,6 +120,8 @@
 
   deps = [
     ":browser",
+    ":fetcher",
+    ":test_support",
     "//base",
     "//base/test:test_support",
     "//components/prefs:test_support",
diff --git a/components/supervised_user/core/browser/fetcher_config_test_utils.cc b/components/supervised_user/core/browser/fetcher_config_test_utils.cc
new file mode 100644
index 0000000..1c26398
--- /dev/null
+++ b/components/supervised_user/core/browser/fetcher_config_test_utils.cc
@@ -0,0 +1,56 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/supervised_user/core/browser/fetcher_config_test_utils.h"
+
+#include "base/logging.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "url/gurl.h"
+
+namespace supervised_user {
+namespace {
+
+const FetcherConfig& Validated(const FetcherConfig& config) {
+  GURL url = GURL(config.service_endpoint).Resolve(config.service_path);
+  CHECK(url.is_valid()) << "Invalid service endpoint or path.";
+  if (config.histogram_basename.empty()) {
+    DLOG(WARNING) << "Histograms are not configured for " << url.spec() << ".";
+  }
+  return config;
+}
+}  // namespace
+
+FetcherTestConfigBuilder::FetcherTestConfigBuilder(
+    const FetcherConfig& from_config)
+    : config_(from_config) {}
+
+FetcherTestConfigBuilder FetcherTestConfigBuilder::FromConfig(
+    const FetcherConfig& from_config) {
+  return FetcherTestConfigBuilder(from_config);
+}
+
+FetcherTestConfigBuilder& FetcherTestConfigBuilder::WithServiceEndpoint(
+    base::StringPiece value) {
+  config_.service_endpoint = value;
+  return *this;
+}
+
+FetcherTestConfigBuilder& FetcherTestConfigBuilder::WithServicePath(
+    base::StringPiece value) {
+  config_.service_path = value;
+  return *this;
+}
+
+FetcherTestConfigBuilder& FetcherTestConfigBuilder::WithHistogramBasename(
+    base::StringPiece value) {
+  config_.histogram_basename = value;
+  return *this;
+}
+
+FetcherConfig FetcherTestConfigBuilder::Build() const {
+  return Validated(config_);
+}
+
+}  // namespace supervised_user
diff --git a/components/supervised_user/core/browser/fetcher_config_test_utils.h b/components/supervised_user/core/browser/fetcher_config_test_utils.h
new file mode 100644
index 0000000..d78d96d
--- /dev/null
+++ b/components/supervised_user/core/browser/fetcher_config_test_utils.h
@@ -0,0 +1,29 @@
+
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_TEST_UTILS_H_
+#define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_TEST_UTILS_H_
+
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
+
+namespace supervised_user {
+
+// Test utility for overriding configurations for KidsExternalFetcher.
+class FetcherTestConfigBuilder {
+ public:
+  static FetcherTestConfigBuilder FromConfig(const FetcherConfig& from_config);
+  FetcherTestConfigBuilder& WithServiceEndpoint(base::StringPiece value);
+  FetcherTestConfigBuilder& WithServicePath(base::StringPiece value);
+  FetcherTestConfigBuilder& WithHistogramBasename(base::StringPiece value);
+  FetcherConfig Build() const;
+
+ private:
+  explicit FetcherTestConfigBuilder(const FetcherConfig& base);
+  FetcherConfig config_;
+};
+
+}  // namespace supervised_user
+
+#endif  // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_TEST_UTILS_H_
diff --git a/components/supervised_user/core/browser/kids_external_fetcher.cc b/components/supervised_user/core/browser/kids_external_fetcher.cc
index c6b2ba9..1c9f52c 100644
--- a/components/supervised_user/core/browser/kids_external_fetcher.cc
+++ b/components/supervised_user/core/browser/kids_external_fetcher.cc
@@ -12,6 +12,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
+#include "base/notreached.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
@@ -21,6 +22,8 @@
 #include "components/signin/public/identity_manager/access_token_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/supervised_user/core/browser/kids_access_token_fetcher.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_requests.h"
 #include "components/supervised_user/core/common/supervised_user_constants.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "net/http/http_status_code.h"
@@ -28,6 +31,7 @@
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
+#include "url/gurl.h"
 
 namespace {
 // Controls the retry count of the simple url loader.
@@ -43,8 +47,6 @@
 using ::base::UmaHistogramSparse;
 using ::base::UmaHistogramTimes;
 using ::base::Unretained;
-using ::kids_chrome_management::ListFamilyMembersRequest;
-using ::kids_chrome_management::ListFamilyMembersResponse;
 using ::network::ResourceRequest;
 using ::signin::IdentityManager;
 
@@ -71,15 +73,15 @@
   return loader.ResponseInfo()->headers->response_code();
 }
 
+// TODO(b/276898959): Support payload for POST requests.
 std::unique_ptr<network::SimpleURLLoader> InitializeSimpleUrlLoader(
-    StringPiece payload,
     StringPiece access_token,
-    const GURL& url,
-    net::NetworkTrafficAnnotationTag traffic_annotation) {
+    const supervised_user::FetcherConfig& fetcher_config,
+    const GURL& url) {
   std::unique_ptr<ResourceRequest> resource_request =
       std::make_unique<ResourceRequest>();
   resource_request->url = url;
-  resource_request->method = "GET";
+  resource_request->method = fetcher_config.GetHttpMethod();
   resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
   resource_request->headers.SetHeader(
       net::HttpRequestHeaders::kAuthorization,
@@ -87,115 +89,16 @@
                          access_token));
   std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
       network::SimpleURLLoader::Create(std::move(resource_request),
-                                       traffic_annotation);
+                                       fetcher_config.traffic_annotation());
   simple_url_loader->SetRetryOptions(
       kNumFamilyInfoFetcherRetries,
       network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
   return simple_url_loader;
 }
 
-template <typename Request>
-std::string ConvertRequestTypeToMetricLabel();
-template <>
-std::string ConvertRequestTypeToMetricLabel<ListFamilyMembersRequest>() {
-  return "ListFamilyMembersRequest";
-}
-
-// Metric key
-template <typename Request>
-std::string CreateMetricKey(StringPiece metric_id) {
-  return JoinString(
-      {"Signin", ConvertRequestTypeToMetricLabel<Request>(), metric_id}, ".");
-}
-template <typename Request>
-std::string CreateMetricKey(StringPiece metric_id, StringPiece metric_suffix) {
-  return JoinString({"Signin", ConvertRequestTypeToMetricLabel<Request>(),
-                     metric_id, metric_suffix},
-                    ".");
-}
-
-// The returned value must match one of the labels in
-// chromium/src/tools/metrics/histograms/enums.xml/histogram-configuration/enums/enum[@name='KidsExternalFetcherStatus'],
-// and should be reflected in tokens in
-// chromium/src/tools/metrics/histograms/metadata/signin/histograms.xml/histogram-configuration/histograms/histogram[@name='Signin.ListFamilyMembersRequest.{Status}.*']
-std::string ConvertStateToMetricLabel(KidsExternalFetcherStatus::State state) {
-  switch (state) {
-    case KidsExternalFetcherStatus::OK:
-      return "NoError";
-    case KidsExternalFetcherStatus::GOOGLE_SERVICE_AUTH_ERROR:
-      return "AuthError";
-    case KidsExternalFetcherStatus::NET_OR_HTTP_ERROR:
-      return "HttpError";
-    case KidsExternalFetcherStatus::INVALID_RESPONSE:
-      return "ParseError";
-    case KidsExternalFetcherStatus::DATA_ERROR:
-      return "DataError";
-  }
-}
-
-// Determines the response type. See go/system-parameters to verity list of
-// possible One Platform system params.
-const std::string& GetSystemParameters() {
-  static const base::NoDestructor<std::string> nonce("alt=proto");
-  return *nonce;
-}
-
-// Controls what endpoint to call for given Request.
-template <typename Request>
-const std::string& GetPathForRequest(const Request& request);
-
-template <>
-const std::string& GetPathForRequest(const ListFamilyMembersRequest& request) {
-  static const base::NoDestructor<std::string> nonce(
-      StrCat({"families/mine/members?", GetSystemParameters()}));
-  return *nonce;
-}
-
-template <typename Request>
-net::NetworkTrafficAnnotationTag GetDefaultNetworkTrafficAnnotationTag();
-
-template <>
-net::NetworkTrafficAnnotationTag
-GetDefaultNetworkTrafficAnnotationTag<ListFamilyMembersRequest>() {
-  return net::DefineNetworkTrafficAnnotation(
-      "kids_chrome_management_list_family_members", R"(
-        semantics {
-          sender: "Supervised Users"
-          description:
-            "Fetches information about the user's family group from the Google "
-            "Family API."
-          trigger:
-            "Triggered in regular intervals to update profile information."
-          data:
-            "The request is authenticated with an OAuth2 access token "
-            "identifying the Google account. No other information is sent."
-          destination: GOOGLE_OWNED_SERVICE
-          user_data {
-            type: NONE
-          }
-          internal {
-            contacts {
-              email: "chrome-kids-eng@google.com"
-            }
-          }
-          last_reviewed: "2023-04-18"
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "This feature cannot be disabled in settings and is only enabled "
-            "for child accounts. If sign-in is restricted to accounts from a "
-            "managed domain, those accounts are not going to be child accounts."
-          chrome_policy {
-            RestrictSigninToPattern {
-              policy_options {mode: MANDATORY}
-              RestrictSigninToPattern: "*@manageddomain.com"
-            }
-          }
-        })");
-}
-
 // A fetcher with underlying network::SharedURLLoaderFactory.
+// Internally, it's a two-phase process: first the access token is fetched, and
+// if applicable, the remote service is called and the response is processed.
 template <typename Request, typename Response>
 class FetcherImpl final : public KidsExternalFetcher<Request, Response> {
  private:
@@ -206,54 +109,69 @@
   explicit FetcherImpl(
       IdentityManager& identity_manager,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-      StringPiece url,
-      Request request,
-      Callback callback) {
+      const supervised_user::FetcherConfig& fetcher_config,
+      Callback callback)
+      : config_(fetcher_config) {
     access_token_fetcher_ = std::make_unique<KidsAccessTokenFetcher>(
         identity_manager,
-        BindOnce(&FetcherImpl::StartRequest, Unretained(this),
-                 url_loader_factory, GURL(url), request,
+        BindOnce(&FetcherImpl::OnAccessTokenFetchComplete, Unretained(this),
+                 url_loader_factory,
                  std::move(callback)));  // Unretained(.) is safe because `this`
                                          // owns `access_token_fetcher_`.
   }
 
-  // Not copyable
+  // Not copyable.
   FetcherImpl(const FetcherImpl&) = delete;
   FetcherImpl& operator=(const FetcherImpl&) = delete;
 
  private:
-  static void WrapCallbackWithMetrics(Callback callback,
-                                      TimeTicks start_time,
-                                      KidsExternalFetcherStatus status,
-                                      std::unique_ptr<Response> response) {
+  void RecordStabilityMetrics(TimeDelta latency,
+                              KidsExternalFetcherStatus status) {
+    UmaHistogramEnumeration(GetMetricKey("Status"), status.state());
+    UmaHistogramTimes(GetMetricKey("Latency"), latency);
+    UmaHistogramTimes(GetMetricKey("Latency", status.ToMetricEnumLabel()),
+                      latency);
+  }
+
+  void WrapCallbackWithMetrics(Callback callback,
+                               TimeTicks start_time,
+                               KidsExternalFetcherStatus status,
+                               std::unique_ptr<Response> response) {
     TimeDelta latency = TimeTicks::Now() - start_time;
-    UmaHistogramEnumeration(CreateMetricKey<Request>("Status"), status.state());
+    RecordStabilityMetrics(latency, status);
+
+    // Record additional metrics for various failures.
     if (status.state() == KidsExternalFetcherStatus::State::NET_OR_HTTP_ERROR) {
-      UmaHistogramSparse(CreateMetricKey<Request>("NetOrHttpStatus"),
+      UmaHistogramSparse(GetMetricKey("NetOrHttpStatus"),
                          status.net_or_http_error_code().value());
     }
-    UmaHistogramTimes(CreateMetricKey<Request>("Latency"), latency);
-    UmaHistogramTimes(CreateMetricKey<Request>(
-                          "Latency", ConvertStateToMetricLabel(status.state())),
-                      latency);
 
     DCHECK(
         callback);  // https://chromium.googlesource.com/chromium/src/+/main/docs/callback.md#creating-a-callback-that-does-nothing
     std::move(callback).Run(status, std::move(response));
   }
 
-  void StartRequest(
+  std::string GetMetricKey(base::StringPiece metric_id) const {
+    return JoinString({config_.histogram_basename, metric_id}, ".");
+  }
+  std::string GetMetricKey(base::StringPiece metric_id,
+                           base::StringPiece metric_suffix) const {
+    return JoinString({config_.histogram_basename, metric_id, metric_suffix},
+                      ".");
+  }
+
+  // First phase of fetching done: the access token response is ready.
+  void OnAccessTokenFetchComplete(
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-      GURL endpoint,
-      Request request,
       Callback callback,
       base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>
           access_token) {
     DCHECK(
         callback);  // https://chromium.googlesource.com/chromium/src/+/main/docs/callback.md#creating-a-callback-that-does-nothing
 
-    Callback callback_with_metrics = BindOnce(
-        WrapCallbackWithMetrics, std::move(callback), TimeTicks::Now());
+    Callback callback_with_metrics =
+        BindOnce(&FetcherImpl::WrapCallbackWithMetrics, Unretained(this),
+                 std::move(callback), TimeTicks::Now());
 
     if (!access_token.has_value()) {
       std::move(callback_with_metrics)
@@ -263,13 +181,10 @@
       return;
     }
 
-    StringPiece token_value = access_token.value().token;
-    net::NetworkTrafficAnnotationTag traffic_annotation =
-        GetDefaultNetworkTrafficAnnotationTag<Request>();
-
+    // TODO(b/276898959): add optional payload for POST requests.
     simple_url_loader_ = InitializeSimpleUrlLoader(
-        request.SerializeAsString(), token_value,
-        endpoint.Resolve(GetPathForRequest(request)), traffic_annotation);
+        access_token.value().token, config_,
+        supervised_user::CreateRequestUrl<Request>(config_));
 
     simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
         url_loader_factory.get(),
@@ -280,6 +195,7 @@
                                            // `this` owns `simple_url_loader_`.
   }
 
+  // Second phase of fetching done: the remote service responded.
   void OnSimpleUrlLoaderComplete(Callback callback,
                                  std::unique_ptr<std::string> response_body) {
     if (!IsLoadingSuccessful(*simple_url_loader_) ||
@@ -303,16 +219,8 @@
 
   std::unique_ptr<KidsAccessTokenFetcher> access_token_fetcher_;
   std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
+  const supervised_user::FetcherConfig config_;
 };
-
-template class FetcherImpl<ListFamilyMembersRequest, ListFamilyMembersResponse>;
-
-ListFamilyMembersRequest CreateListFamilyMembersRequest() {
-  ListFamilyMembersRequest request;
-  request.set_family_id("mine");  // Required by the contract of the protocol,
-                                  // see proto definition.
-  return request;
-}
 }  // namespace
 
 // Main constructor, referenced by the rest.
@@ -401,6 +309,26 @@
   }
 }
 
+// The returned value must match one of the labels in
+// chromium/src/tools/metrics/histograms/enums.xml/histogram-configuration/enums/enum[@name='KidsExternalFetcherStatus'],
+// and should be reflected in tokens in histogram defined for this fetcher.
+// See example at
+// chromium/src/tools/metrics/histograms/metadata/signin/histograms.xml/histogram-configuration/histograms/histogram[@name='Signin.ListFamilyMembersRequest.{Status}.*']
+std::string KidsExternalFetcherStatus::ToMetricEnumLabel() const {
+  switch (state_) {
+    case KidsExternalFetcherStatus::OK:
+      return "NoError";
+    case KidsExternalFetcherStatus::GOOGLE_SERVICE_AUTH_ERROR:
+      return "AuthError";
+    case KidsExternalFetcherStatus::NET_OR_HTTP_ERROR:
+      return "HttpError";
+    case KidsExternalFetcherStatus::INVALID_RESPONSE:
+      return "ParseError";
+    case KidsExternalFetcherStatus::DATA_ERROR:
+      return "DataError";
+  }
+}
+
 KidsExternalFetcherStatus::State KidsExternalFetcherStatus::state() const {
   return state_;
 }
@@ -414,16 +342,19 @@
   return google_service_auth_error_;
 }
 
+// Fetcher factories.
 std::unique_ptr<
-    KidsExternalFetcher<ListFamilyMembersRequest, ListFamilyMembersResponse>>
+    KidsExternalFetcher<kids_chrome_management::ListFamilyMembersRequest,
+                        kids_chrome_management::ListFamilyMembersResponse>>
 FetchListFamilyMembers(
     IdentityManager& identity_manager,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-    StringPiece url,
-    KidsExternalFetcher<ListFamilyMembersRequest,
-                        ListFamilyMembersResponse>::Callback callback) {
+    KidsExternalFetcher<
+        kids_chrome_management::ListFamilyMembersRequest,
+        kids_chrome_management::ListFamilyMembersResponse>::Callback callback,
+    const supervised_user::FetcherConfig& config) {
   return std::make_unique<
-      FetcherImpl<ListFamilyMembersRequest, ListFamilyMembersResponse>>(
-      identity_manager, url_loader_factory, url,
-      CreateListFamilyMembersRequest(), std::move(callback));
+      FetcherImpl<kids_chrome_management::ListFamilyMembersRequest,
+                  kids_chrome_management::ListFamilyMembersResponse>>(
+      identity_manager, url_loader_factory, config, std::move(callback));
 }
diff --git a/components/supervised_user/core/browser/kids_external_fetcher.h b/components/supervised_user/core/browser/kids_external_fetcher.h
index a2e23e1..92a0859 100644
--- a/components/supervised_user/core/browser/kids_external_fetcher.h
+++ b/components/supervised_user/core/browser/kids_external_fetcher.h
@@ -12,9 +12,11 @@
 #include "base/strings/string_piece.h"
 #include "base/types/strong_alias.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
 #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "url/gurl.h"
 
 // -----------------------------------------------------------------------------
 // Usage documentation
@@ -27,18 +29,14 @@
 // * serializing the request and parsing the response,
 // * submitting metrics.
 //
-// If you want to create new fetcher factory method, then some implementation
+// If you want to create new fetcher factory method, then some
 // details must be provided in order to enable fetching for said <Request,
 // Response> pair. The new fetcher factory should have at least the following
-// arguments: signin::IdentityManager, network::SharedURLLoaderFactory, url of
-// the endpoint and consuming callback provided.
+// arguments: signin::IdentityManager, network::SharedURLLoaderFactory,
+// consuming callback and must reference a static configuration.
 //
-// In the corresponding cc file, there should be:
-// * a traffic annotation tag for the request, assuming that one Request
-// represents one API endpoint, in the implementation cc file (example:
-// GetDefaultNetworkTrafficAnnotationTag),
-// * a request path method for the request (example: GetPathForRequest),
-// * a metrics key constructing method (example: CreateMetricKey).
+// The static configuration should be placed in the
+// kids_external_fetcher_config.h module.
 
 // Holds the status of the fetch. The callback's response will be set iff the
 // status is ok.
@@ -97,6 +95,10 @@
   // Returns a message describing the status.
   std::string ToString() const;
 
+  // Translate the status to metric enum label as defined in
+  // tools/metrics/histograms/enums.xml.
+  std::string ToMetricEnumLabel() const;
+
   State state() const;
   NetOrHttpErrorType net_or_http_error_code() const;
   const class GoogleServiceAuthError& google_service_auth_error() const;
@@ -138,9 +140,10 @@
 FetchListFamilyMembers(
     signin::IdentityManager& identity_manager,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-    base::StringPiece url,
     KidsExternalFetcher<
         kids_chrome_management::ListFamilyMembersRequest,
-        kids_chrome_management::ListFamilyMembersResponse>::Callback callback);
+        kids_chrome_management::ListFamilyMembersResponse>::Callback callback,
+    const supervised_user::FetcherConfig& config =
+        supervised_user::kListFamilyMembersConfig);
 
 #endif  // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_H_
diff --git a/components/supervised_user/core/browser/kids_external_fetcher_config.cc b/components/supervised_user/core/browser/kids_external_fetcher_config.cc
new file mode 100644
index 0000000..b92dadb
--- /dev/null
+++ b/components/supervised_user/core/browser/kids_external_fetcher_config.cc
@@ -0,0 +1,65 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
+
+#include <string>
+
+#include "base/notreached.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+
+namespace supervised_user {
+
+namespace annotations {
+net::NetworkTrafficAnnotationTag ListFamilyMembersTag() {
+  return net::DefineNetworkTrafficAnnotation(
+      "kids_chrome_management_list_family_members",
+      R"(
+semantics {
+  sender: "Supervised Users"
+  description:
+    "Fetches information about the user's family group from the Google "
+    "Family API."
+  trigger:
+    "Triggered in regular intervals to update profile information."
+  data:
+    "The request is authenticated with an OAuth2 access token "
+    "identifying the Google account. No other information is sent."
+  destination: GOOGLE_OWNED_SERVICE
+  user_data {
+    type: NONE
+  }
+  internal {
+    contacts {
+      email: "chrome-kids-eng@google.com"
+    }
+  }
+  last_reviewed: "2023-05-02"
+}
+policy {
+  cookies_allowed: NO
+  setting:
+    "This feature cannot be disabled in settings and is only enabled "
+    "for child accounts. If sign-in is restricted to accounts from a "
+    "managed domain, those accounts are not going to be child accounts."
+  chrome_policy {
+    RestrictSigninToPattern {
+      policy_options {mode: MANDATORY}
+      RestrictSigninToPattern: "*@manageddomain.com"
+    }
+  }
+})");
+}
+}  // namespace annotations
+
+std::string FetcherConfig::GetHttpMethod() const {
+  switch (method) {
+    case Method::kGet:
+      return "GET";
+    default:
+      NOTREACHED_NORETURN();
+  }
+}
+
+}  // namespace supervised_user
diff --git a/components/supervised_user/core/browser/kids_external_fetcher_config.h b/components/supervised_user/core/browser/kids_external_fetcher_config.h
new file mode 100644
index 0000000..45b4e84e
--- /dev/null
+++ b/components/supervised_user/core/browser/kids_external_fetcher_config.h
@@ -0,0 +1,55 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_CONFIG_H_
+#define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_CONFIG_H_
+
+#include <string>
+
+#include "base/memory/raw_ptr.h"
+#include "base/strings/string_piece.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "url/gurl.h"
+
+namespace supervised_user {
+
+namespace annotations {
+// Traffic annotations can only live in cc/mm files.
+net::NetworkTrafficAnnotationTag ListFamilyMembersTag();
+}  // namespace annotations
+
+// Configuration bundle for the KidsExternalFetcher.
+struct FetcherConfig {
+  // TODO(b/276898959): add kPost option.
+  enum class Method { kGet };
+
+  // Primary endpoint of the fetcher.
+  base::StringPiece service_endpoint{
+      "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/"};
+
+  // Path of the service. See the service specification at
+  // google3/google/internal/kids/chrome/v1/kidschromemanagement.proto for
+  // examples.
+  base::StringPiece service_path;
+
+  // HTTP method used to communicate with the service.
+  Method method;
+
+  // Basename for histograms
+  base::StringPiece histogram_basename;
+
+  net::NetworkTrafficAnnotationTag (*traffic_annotation)();
+
+  std::string GetHttpMethod() const;
+};
+
+constexpr FetcherConfig kListFamilyMembersConfig{
+    .service_path = "families/mine/members",
+    .method = FetcherConfig::Method::kGet,
+    .histogram_basename = "Signin.ListFamilyMembersRequest",
+    .traffic_annotation = annotations::ListFamilyMembersTag,
+};
+}  // namespace supervised_user
+
+#endif  // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_CONFIG_H_
diff --git a/components/supervised_user/core/browser/kids_external_fetcher_requests.h b/components/supervised_user/core/browser/kids_external_fetcher_requests.h
new file mode 100644
index 0000000..096d4d7
--- /dev/null
+++ b/components/supervised_user/core/browser/kids_external_fetcher_requests.h
@@ -0,0 +1,31 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_REQUESTS_H_
+#define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_KIDS_EXTERNAL_FETCHER_REQUESTS_H_
+
+#include "base/strings/strcat.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
+#include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
+#include "url/gurl.h"
+
+namespace supervised_user {
+
+// Determines the response type. See go/system-parameters to see list of
+// possible One Platform system params.
+constexpr base::StringPiece kSystemParameters("alt=proto");
+
+// Creates a requests for kids management api which is independent from the
+// current profile (doesn't take Profile* parameter). It also adds query
+// parameter that configures the remote endpoint to respond with a protocol
+// buffer message.
+template <typename RequestType>
+GURL CreateRequestUrl(const FetcherConfig& config) {
+  return GURL(config.service_endpoint)
+      .Resolve(base::StrCat({config.service_path, "?", kSystemParameters}));
+}
+
+}  // namespace supervised_user
+
+#endif
diff --git a/components/supervised_user/core/browser/kids_external_fetcher_unittest.cc b/components/supervised_user/core/browser/kids_external_fetcher_unittest.cc
index d8dd0db..7198001 100644
--- a/components/supervised_user/core/browser/kids_external_fetcher_unittest.cc
+++ b/components/supervised_user/core/browser/kids_external_fetcher_unittest.cc
@@ -11,6 +11,8 @@
 #include "base/time/time.h"
 #include "base/types/expected.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/supervised_user/core/browser/fetcher_config_test_utils.h"
+#include "components/supervised_user/core/browser/kids_external_fetcher_config.h"
 #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "net/http/http_status_code.h"
@@ -31,11 +33,18 @@
 using ::network::TestURLLoaderFactory;
 using ::signin::ConsentLevel;
 using ::signin::IdentityTestEnvironment;
+using ::supervised_user::FetcherConfig;
+using ::supervised_user::FetcherTestConfigBuilder;
 using ::testing::Test;
 
 // Tests the Kids External API fetchers functionality.
 class KidsExternalFetcherTest : public Test {
  protected:
+  FetcherConfig test_fetcher_config_ =
+      FetcherTestConfigBuilder::FromConfig(
+          supervised_user::kListFamilyMembersConfig)
+          .WithServiceEndpoint("http://example.com")
+          .Build();
   network::TestURLLoaderFactory test_url_loader_factory_;
   base::test::TaskEnvironment task_environment_;
   IdentityTestEnvironment identity_test_env_;
@@ -70,10 +79,11 @@
 
   auto fetcher = FetchListFamilyMembers(
       *identity_test_env_.identity_manager(),
-      test_url_loader_factory_.GetSafeWeakWrapper(), "http://example.com",
+      test_url_loader_factory_.GetSafeWeakWrapper(),
       BindOnce(&Receiver<ListFamilyMembersRequest,
                          ListFamilyMembersResponse>::Receive,
-               base::Unretained(&receiver)));
+               base::Unretained(&receiver)),
+      test_fetcher_config_);
   identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       "access_token", Time::Max());
 
@@ -96,10 +106,11 @@
 
   auto fetcher = FetchListFamilyMembers(
       *identity_test_env_.identity_manager(),
-      test_url_loader_factory_.GetSafeWeakWrapper(), "http://example.com/",
+      test_url_loader_factory_.GetSafeWeakWrapper(),
       BindOnce(&Receiver<ListFamilyMembersRequest,
                          ListFamilyMembersResponse>::Receive,
-               base::Unretained(&receiver)));
+               base::Unretained(&receiver)),
+      test_fetcher_config_);
   identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
       GoogleServiceAuthError(
           GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
@@ -118,10 +129,11 @@
 
   auto fetcher = FetchListFamilyMembers(
       *identity_test_env_.identity_manager(),
-      test_url_loader_factory_.GetSafeWeakWrapper(), "http://example.com/",
+      test_url_loader_factory_.GetSafeWeakWrapper(),
       BindOnce(&Receiver<ListFamilyMembersRequest,
                          ListFamilyMembersResponse>::Receive,
-               base::Unretained(&receiver)));
+               base::Unretained(&receiver)),
+      test_fetcher_config_);
   identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       "access_token", Time::Max());
 
@@ -147,10 +159,11 @@
 
   auto fetcher = FetchListFamilyMembers(
       *identity_test_env_.identity_manager(),
-      test_url_loader_factory_.GetSafeWeakWrapper(), "http://example.com/",
+      test_url_loader_factory_.GetSafeWeakWrapper(),
       BindOnce(&Receiver<ListFamilyMembersRequest,
                          ListFamilyMembersResponse>::Receive,
-               base::Unretained(&receiver)));
+               base::Unretained(&receiver)),
+      test_fetcher_config_);
 
   identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       "access_token", Time::Max());
diff --git a/components/supervised_user/core/common/pref_names.cc b/components/supervised_user/core/common/pref_names.cc
index 3d3eb59..c5fe4bc 100644
--- a/components/supervised_user/core/common/pref_names.cc
+++ b/components/supervised_user/core/common/pref_names.cc
@@ -101,4 +101,11 @@
 const char kDefaultSupervisedUserFilteringBehavior[] =
     "profile.managed.default_filtering_behavior";
 
+// An integer pref that stores the current state of the interstitial banner for
+// a supervised user (SupervisedUserFilter::FirstTimeInterstitialBannerState):
+// 0: kNeedToShow
+// 1: kSetupComplete
+// 2: kUnknown
+const char kFirstTimeInterstitialBannerState[] = "profile.managed.banner_state";
+
 }  // namespace prefs
diff --git a/components/supervised_user/core/common/pref_names.h b/components/supervised_user/core/common/pref_names.h
index 84709a4..2386603b 100644
--- a/components/supervised_user/core/common/pref_names.h
+++ b/components/supervised_user/core/common/pref_names.h
@@ -34,6 +34,8 @@
 
 extern const char kDefaultSupervisedUserFilteringBehavior[];
 
+extern const char kFirstTimeInterstitialBannerState[];
+
 }  // namespace prefs
 
 #endif  // COMPONENTS_SUPERVISED_USER_CORE_COMMON_PREF_NAMES_H_
diff --git a/components/supervised_user/core/common/supervised_user_utils.h b/components/supervised_user/core/common/supervised_user_utils.h
index eec236ce..702e1d4e 100644
--- a/components/supervised_user/core/common/supervised_user_utils.h
+++ b/components/supervised_user/core/common/supervised_user_utils.h
@@ -22,6 +22,21 @@
   NOT_SIGNED_IN = 5,
 };
 
+// This enum describes the state of the interstitial banner that is shown for
+// when previous supervised users of desktop see the interstitial for the first
+// time after desktop controls are enabled.
+enum class FirstTimeInterstitialBannerState : int {
+  // Supervised users should see banner the next time the interstitial is
+  // triggered.
+  kNeedToShow = 0,
+
+  // Banner has been shown to supervised user if needed.
+  kSetupComplete = 1,
+
+  // Banner state has not been set.
+  kUnknown = 2,
+};
+
 // Converts FilteringBehaviorReason enum to string format.
 std::string FilteringBehaviorReasonToString(FilteringBehaviorReason reason);
 
diff --git a/content/BUILD.gn b/content/BUILD.gn
index b15e6e2..5123b9eb 100644
--- a/content/BUILD.gn
+++ b/content/BUILD.gn
@@ -106,15 +106,6 @@
   }
 }
 
-grit("dev_ui_content_resources") {
-  source = "dev_ui_content_resources.grd"
-
-  outputs = [
-    "grit/dev_ui_content_resources.h",
-    "dev_ui_content_resources.pak",
-  ]
-}
-
 # This target exists to "hold" the content_export header so we can do proper
 # inclusion testing of it.
 source_set("export") {
diff --git a/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm
index da029fb..fdf66fe1 100644
--- a/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm
+++ b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <memory>
-
 #import "base/mac/foundation_util.h"
 #import "base/mac/mac_util.h"
+#include "base/mac/scoped_nsobject.h"
 #include "base/mac/scoped_objc_class_swizzler.h"
 #import "base/task/single_thread_task_runner.h"
 #include "base/test/scoped_feature_list.h"
@@ -16,10 +15,6 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/content_browser_test.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 using remote_cocoa::mojom::DraggingInfo;
 using remote_cocoa::mojom::DraggingInfoPtr;
 using remote_cocoa::mojom::SelectionDirection;
@@ -146,17 +141,17 @@
 - (instancetype)init {
   self = [super init];
 
-  [WebContentVisibilityUpdateWatcher performOcclusionStateUpdatesSwizzler] =
-      std::make_unique<base::mac::ScopedObjCClassSwizzler>(
+  [WebContentVisibilityUpdateWatcher performOcclusionStateUpdatesSwizzler]
+      .reset(new base::mac::ScopedObjCClassSwizzler(
           NSClassFromString(@"WebContentsOcclusionCheckerMac"),
           [WebContentVisibilityUpdateWatcher class],
-          @selector(performOcclusionStateUpdates));
+          @selector(performOcclusionStateUpdates)));
 
-  [WebContentVisibilityUpdateWatcher setWebContentsOccludedSwizzler] =
-      std::make_unique<base::mac::ScopedObjCClassSwizzler>(
+  [WebContentVisibilityUpdateWatcher setWebContentsOccludedSwizzler].reset(
+      new base::mac::ScopedObjCClassSwizzler(
           NSClassFromString(@"WebContentsViewCocoa"),
           [WebContentVisibilityUpdateWatcher class],
-          @selector(performDelayedSetWebContentsOccluded));
+          @selector(performDelayedSetWebContentsOccluded)));
 
   return self;
 }
@@ -165,6 +160,7 @@
   [WebContentVisibilityUpdateWatcher performOcclusionStateUpdatesSwizzler]
       .reset();
   [WebContentVisibilityUpdateWatcher setWebContentsOccludedSwizzler].reset();
+  [super dealloc];
 }
 
 - (void)waitForOcclusionUpdate:(NSTimeInterval)delayInMilliseconds {
@@ -233,11 +229,11 @@
   self = [super init];
 
   // Set up the swizzling.
-  [WebContentVisibilityUpdateCounter swizzler] =
-      std::make_unique<base::mac::ScopedObjCClassSwizzler>(
+  [WebContentVisibilityUpdateCounter swizzler].reset(
+      new base::mac::ScopedObjCClassSwizzler(
           NSClassFromString(@"WebContentsOcclusionCheckerMac"),
           [WebContentVisibilityUpdateCounter class],
-          @selector(scheduleOcclusionStateUpdates));
+          @selector(scheduleOcclusionStateUpdates)));
 
   [WebContentVisibilityUpdateCounter methodInvocationCount] = kNeverCalled;
 
@@ -246,6 +242,7 @@
 
 - (void)dealloc {
   [WebContentVisibilityUpdateCounter methodInvocationCount] = 0;
+  [super dealloc];
 }
 
 - (void)scheduleOcclusionStateUpdates {
@@ -268,7 +265,7 @@
 class WebContentsNSViewHostStub
     : public remote_cocoa::mojom::WebContentsNSViewHost {
  public:
-  WebContentsNSViewHostStub() = default;
+  WebContentsNSViewHostStub() {}
 
   void OnMouseEvent(bool motion, bool exited) override {}
 
@@ -338,10 +335,10 @@
         params["EnhancedWindowOcclusionDetection"] = "true";
       if (GetParam().display_sleep_detection_enabled)
         params["DisplaySleepAndAppHideDetection"] = "true";
-      features_.InitAndEnableFeatureWithParameters(
+      _features.InitAndEnableFeatureWithParameters(
           features::kMacWebContentsOcclusion, params);
     } else {
-      features_.InitAndDisableFeature(features::kMacWebContentsOcclusion);
+      _features.InitAndDisableFeature(features::kMacWebContentsOcclusion);
     }
   }
 
@@ -353,7 +350,7 @@
     ContentBrowserTest::SetUp();
   }
 
-  ~WindowOcclusionBrowserTestMac() override {
+  ~WindowOcclusionBrowserTestMac() {
     [NSClassFromString(@"WebContentsOcclusionCheckerMac")
         resetSharedInstanceForTesting];
   }
@@ -363,23 +360,21 @@
         [NSMutableArray array];
 
     [allWebContentsViewCocoa
-        addObjectsFromArray:[window_a_ webContentsViewCocoa]];
+        addObjectsFromArray:[window_a webContentsViewCocoa]];
     [allWebContentsViewCocoa
-        addObjectsFromArray:[window_b_ webContentsViewCocoa]];
+        addObjectsFromArray:[window_b webContentsViewCocoa]];
 
     // Add these explicitly, in case they've been removed from their host
     // windows.
-    if (window_a_web_contents_view_cocoa_ &&
+    if (window_a_web_contents_view_cocoa &&
         ![allWebContentsViewCocoa
-            containsObject:window_a_web_contents_view_cocoa_]) {
-      [allWebContentsViewCocoa addObject:window_a_web_contents_view_cocoa_];
-    }
+            containsObject:window_a_web_contents_view_cocoa])
+      [allWebContentsViewCocoa addObject:window_a_web_contents_view_cocoa];
 
-    if (window_b_web_contents_view_cocoa_ &&
+    if (window_b_web_contents_view_cocoa &&
         ![allWebContentsViewCocoa
-            containsObject:window_b_web_contents_view_cocoa_]) {
-      [allWebContentsViewCocoa addObject:window_b_web_contents_view_cocoa_];
-    }
+            containsObject:window_b_web_contents_view_cocoa])
+      [allWebContentsViewCocoa addObject:window_b_web_contents_view_cocoa];
 
     for (WebContentsViewCocoa* webContentsViewCocoa in
              allWebContentsViewCocoa) {
@@ -399,8 +394,8 @@
     while ([[NSClassFromString(@"WebContentsOcclusionCheckerMac")
                sharedInstance] occlusionStateUpdatesAreScheduledForTesting] ||
            WebContentsAwaitingUpdates()) {
-      WebContentVisibilityUpdateWatcher* watcher =
-          [[WebContentVisibilityUpdateWatcher alloc] init];
+      base::scoped_nsobject<WebContentVisibilityUpdateWatcher> watcher(
+          [[WebContentVisibilityUpdateWatcher alloc] init]);
       [watcher waitForOcclusionUpdate:1200];
     }
   }
@@ -409,22 +404,22 @@
       NSRect contentRect,
       NSWindowStyleMask styleMask = NSWindowStyleMaskClosable) {
     WebContentsHostWindowForOcclusionTesting* window =
-        [[WebContentsHostWindowForOcclusionTesting alloc]
+        [[[WebContentsHostWindowForOcclusionTesting alloc]
             initWithContentRect:contentRect
                       styleMask:styleMask
                         backing:NSBackingStoreBuffered
-                          defer:YES];
+                          defer:YES] autorelease];
     NSRect window_frame = [NSWindow frameRectForContentRect:contentRect
                                                   styleMask:styleMask];
     window_frame.origin = NSMakePoint(20.0, 200.0);
     [window setFrame:window_frame display:NO];
-    window.releasedWhenClosed = NO;
+    [window setReleasedWhenClosed:NO];
 
     const NSRect kWebContentsFrame = NSMakeRect(0.0, 0.0, 10.0, 10.0);
     WebContentsViewCocoaForOcclusionTesting* web_contents_view =
-        [[WebContentsViewCocoaForOcclusionTesting alloc]
-            initWithFrame:kWebContentsFrame];
-    [window.contentView addSubview:web_contents_view];
+        [[[WebContentsViewCocoaForOcclusionTesting alloc]
+            initWithFrame:kWebContentsFrame] autorelease];
+    [[window contentView] addSubview:web_contents_view];
 
     return web_contents_view;
   }
@@ -432,17 +427,18 @@
   // Creates |window_a| with a visible (i.e. unoccluded) WebContentsViewCocoa.
   void InitWindowA() {
     const NSRect kWindowAContentRect = NSMakeRect(0.0, 0.0, 80.0, 60.0);
-    window_a_web_contents_view_cocoa_ =
-        WebContentsInWindow(kWindowAContentRect);
-    window_a_ = base::mac::ObjCCast<WebContentsHostWindowForOcclusionTesting>(
-        [window_a_web_contents_view_cocoa_ window]);
-    window_a_.title = @"window_a";
+    window_a_web_contents_view_cocoa.reset(
+        [WebContentsInWindow(kWindowAContentRect) retain]);
+    window_a.reset(
+        base::mac::ObjCCast<WebContentsHostWindowForOcclusionTesting>(
+            [[window_a_web_contents_view_cocoa window] retain]));
+    [window_a setTitle:@"window_a"];
 
     // Set up a fake host so we can check the occlusion status.
-    [window_a_web_contents_view_cocoa_ setHost:&host_a_];
+    [window_a_web_contents_view_cocoa setHost:&_host_a];
 
     // Bring the browser window onscreen.
-    OrderWindowFront(window_a_);
+    OrderWindowFront(window_a);
 
     // Init visibility state.
     SetWindowAWebContentsVisibility(remote_cocoa::mojom::Visibility::kVisible);
@@ -450,20 +446,22 @@
 
   void InitWindowB(NSRect window_frame = NSZeroRect) {
     const NSRect kWindowBContentRect = NSMakeRect(0.0, 0.0, 40.0, 40.0);
-    window_b_web_contents_view_cocoa_ =
-        WebContentsInWindow(kWindowBContentRect);
-    window_b_ = base::mac::ObjCCast<WebContentsHostWindowForOcclusionTesting>(
-        window_b_web_contents_view_cocoa_.window);
-    window_b_.title = @"window_b";
+    window_b_web_contents_view_cocoa.reset(
+        [WebContentsInWindow(kWindowBContentRect) retain]);
+    window_b.reset(
+        base::mac::ObjCCast<WebContentsHostWindowForOcclusionTesting>(
+            [[window_b_web_contents_view_cocoa window] retain]));
+    [window_b setTitle:@"window_b"];
 
     if (NSIsEmptyRect(window_frame)) {
-      window_frame.size = [NSWindow frameRectForContentRect:kWindowBContentRect
-                                                  styleMask:window_b_.styleMask]
-                              .size;
+      window_frame.size =
+          [NSWindow frameRectForContentRect:kWindowBContentRect
+                                  styleMask:[window_b styleMask]]
+              .size;
     }
-    [window_b_ setFrame:window_frame display:NO];
+    [window_b setFrame:window_frame display:NO];
 
-    OrderWindowFront(window_b_);
+    OrderWindowFront(window_b);
   }
 
   void OrderWindowFront(NSWindow* window) {
@@ -486,14 +484,14 @@
 
   void OrderWindowOut(NSWindow* window) {
     [window orderWindow:NSWindowOut relativeTo:0];
-    ASSERT_FALSE(window.visible);
+    ASSERT_FALSE([window isVisible]);
 
     WaitForOcclusionUpdate();
   }
 
   void CloseWindow(NSWindow* window) {
     [window close];
-    ASSERT_FALSE(window.visible);
+    ASSERT_FALSE([window isVisible]);
 
     WaitForOcclusionUpdate();
   }
@@ -517,7 +515,7 @@
   }
 
   void SetViewHidden(NSView* view, BOOL hidden) {
-    view.hidden = hidden;
+    [view setHidden:hidden];
 
     WaitForOcclusionUpdate();
   }
@@ -529,15 +527,15 @@
   }
 
   void PostNotification(NSString* notification_name, id object = nil) {
-    [NSNotificationCenter.defaultCenter postNotificationName:notification_name
-                                                      object:object
-                                                    userInfo:nil];
+    [[NSNotificationCenter defaultCenter] postNotificationName:notification_name
+                                                        object:object
+                                                      userInfo:nil];
     WaitForOcclusionUpdate();
   }
 
   void PostWorkspaceNotification(NSString* notification_name) {
-    ASSERT_TRUE(NSWorkspace.sharedWorkspace.notificationCenter);
-    [NSWorkspace.sharedWorkspace.notificationCenter
+    ASSERT_TRUE([[NSWorkspace sharedWorkspace] notificationCenter]);
+    [[[NSWorkspace sharedWorkspace] notificationCenter]
         postNotificationName:notification_name
                       object:nil
                     userInfo:nil];
@@ -545,26 +543,26 @@
   }
 
   remote_cocoa::mojom::Visibility WindowAWebContentsVisibility() {
-    return host_a_.WebContentsVisibility();
+    return _host_a.WebContentsVisibility();
   }
 
   void SetWindowAWebContentsVisibility(
       remote_cocoa::mojom::Visibility visibility) {
-    host_a_.OnWindowVisibilityChanged(visibility);
+    _host_a.OnWindowVisibilityChanged(visibility);
   }
 
   void TearDownInProcessBrowserTestFixture() override {
-    [window_a_web_contents_view_cocoa_ setHost:nullptr];
+    [window_a_web_contents_view_cocoa setHost:nullptr];
   }
 
-  WebContentsHostWindowForOcclusionTesting* __strong window_a_;
-  WebContentsViewCocoa* __strong window_a_web_contents_view_cocoa_;
-  WebContentsHostWindowForOcclusionTesting* __strong window_b_;
-  WebContentsViewCocoa* __strong window_b_web_contents_view_cocoa_;
+  base::scoped_nsobject<WebContentsHostWindowForOcclusionTesting> window_a;
+  base::scoped_nsobject<WebContentsViewCocoa> window_a_web_contents_view_cocoa;
+  base::scoped_nsobject<WebContentsHostWindowForOcclusionTesting> window_b;
+  base::scoped_nsobject<WebContentsViewCocoa> window_b_web_contents_view_cocoa;
 
  private:
-  base::test::ScopedFeatureList features_;
-  WebContentsNSViewHostStub host_a_;
+  base::test::ScopedFeatureList _features;
+  WebContentsNSViewHostStub _host_a;
 };
 
 using WindowOcclusionBrowserTestMacWithoutOcclusionFeature =
@@ -626,7 +624,7 @@
 
   // Create a second window and place it exactly over window_a. The window
   // should still be considered visible.
-  InitWindowB([window_a_ frame]);
+  InitWindowB([window_a frame]);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 }
@@ -641,11 +639,11 @@
             remote_cocoa::mojom::Visibility::kVisible);
 
   // Fake a display sleep notification.
-  ASSERT_TRUE(NSWorkspace.sharedWorkspace.notificationCenter);
-  [[maybe_unused]] WebContentVisibilityUpdateCounter* watcher =
-      [[WebContentVisibilityUpdateCounter alloc] init];
+  ASSERT_TRUE([[NSWorkspace sharedWorkspace] notificationCenter]);
+  base::scoped_nsobject<WebContentVisibilityUpdateCounter> watcher(
+      [[WebContentVisibilityUpdateCounter alloc] init]);
 
-  [NSWorkspace.sharedWorkspace.notificationCenter
+  [[[NSWorkspace sharedWorkspace] notificationCenter]
       postNotificationName:NSWorkspaceScreensDidSleepNotification
                     object:nil
                   userInfo:nil];
@@ -660,14 +658,14 @@
                        MacOSOcclusionNotifications) {
   InitWindowA();
 
-  [window_a_ setOccludedForTesting:YES];
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  [window_a setOccludedForTesting:YES];
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
 
-  [window_a_ setOccludedForTesting:NO];
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  [window_a setOccludedForTesting:NO];
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
@@ -680,7 +678,7 @@
 
   // Create a second window and place it exactly over window_a. Unlike macOS,
   // our manual occlusion detection will determine window_a is occluded.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
@@ -689,20 +687,20 @@
   // state of window_a's web contents.
   const NSSize window_offsets[] = {
       {1.0, 0.0}, {-1.0, 0.0}, {0.0, 1.0}, {0.0, -1.0}};
-  NSRect window_b_frame = window_b_.frame;
-  for (auto window_offset : window_offsets) {
+  NSRect window_b_frame = [window_b frame];
+  for (size_t i = 0; i < std::size(window_offsets); i++) {
     // Move window b so that it no longer completely covers
     // window_a's webcontents.
-    NSRect offset_window_frame =
-        NSOffsetRect(window_b_frame, window_offset.width, window_offset.height);
-    [window_b_ setFrame:offset_window_frame display:YES];
+    NSRect offset_window_frame = NSOffsetRect(
+        window_b_frame, window_offsets[i].width, window_offsets[i].height);
+    [window_b setFrame:offset_window_frame display:YES];
 
     WaitForOcclusionUpdate();
     EXPECT_EQ(WindowAWebContentsVisibility(),
               remote_cocoa::mojom::Visibility::kVisible);
 
     // Move it back.
-    [window_b_ setFrame:window_b_frame display:YES];
+    [window_b setFrame:window_b_frame display:YES];
 
     WaitForOcclusionUpdate();
     EXPECT_EQ(WindowAWebContentsVisibility(),
@@ -718,16 +716,16 @@
 
   // Size and position the second window so that it exactly covers the
   // first.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
 
-  OrderWindowFront(window_a_);
+  OrderWindowFront(window_a);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
-  OrderWindowFront(window_b_);
+  OrderWindowFront(window_b);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
@@ -742,7 +740,7 @@
 
   // Size and position the second window so that it exactly covers the
   // first.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
@@ -750,14 +748,14 @@
   // Fake the start of a live resize. window_a's web contents should
   // become kVisible because resizing window_b may expose whatever's
   // behind it.
-  PostNotification(NSWindowWillStartLiveResizeNotification, window_b_);
+  PostNotification(NSWindowWillStartLiveResizeNotification, window_b);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // Fake the resize end, which should return window_a to kOccluded because
   // it's still completely covered by window_b.
-  PostNotification(NSWindowDidEndLiveResizeNotification, window_b_);
+  PostNotification(NSWindowDidEndLiveResizeNotification, window_b);
   WaitForOcclusionUpdate();
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
@@ -773,13 +771,13 @@
 
   // Size and position the second window so that it exactly covers the
   // first.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
 
   // Close window b.
-  CloseWindow(window_b_);
+  CloseWindow(window_b);
 
   // window_a's web contents should be kVisible, so that it's properly
   // updated when window_b goes offscreen.
@@ -796,22 +794,23 @@
 
   // Size and position the second window so that it exactly covers the
   // first.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
 
   // Create a window_c on top of them both.
   const NSRect kWindowCContentRect = NSMakeRect(0.0, 0.0, 80.0, 60.0);
-  NSWindow* window_c = [WebContentsInWindow(kWindowCContentRect) window];
-  window_c.title = @"window_c";
+  base::scoped_nsobject<NSWindow> window_c(
+      [[WebContentsInWindow(kWindowCContentRect) window] retain]);
+  [window_c setTitle:@"window_c"];
 
   // Configure it for the test.
-  [window_c setFrame:window_a_.frame display:NO];
+  [window_c setFrame:[window_a frame] display:NO];
   OrderWindowFront(window_c);
 
   // Close window_b.
-  CloseWindow(window_b_);
+  CloseWindow(window_b);
   WaitForOcclusionUpdate();
 
   // window_a's web contents should remain kOccluded because of window_c.
@@ -849,23 +848,23 @@
     IgnoreOcclusionUpdatesBetweenWindowFullscreenTransitionNotifications) {
   InitWindowA();
 
-  [window_a_ setOccluded:NO];
-  [window_a_ setOccludedForTesting:NO];
+  [window_a setOccluded:NO];
+  [window_a setOccludedForTesting:NO];
 
   // Fake a fullscreen transition notification.
-  PostNotification(NSWindowWillEnterFullScreenNotification, window_a_);
+  PostNotification(NSWindowWillEnterFullScreenNotification, window_a);
 
   // An occlusion change should have no effect while in transition.
-  [window_a_ setOccludedForTesting:YES];
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  [window_a setOccludedForTesting:YES];
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // End the transition.
-  PostNotification(NSWindowDidExitFullScreenNotification, window_a_);
+  PostNotification(NSWindowDidExitFullScreenNotification, window_a);
 
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   WaitForOcclusionUpdate();
 
@@ -876,26 +875,26 @@
             remote_cocoa::mojom::Visibility::kOccluded);
 
   // Reset.
-  [window_a_ setOccluded:NO];
-  [window_a_ setOccludedForTesting:NO];
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  [window_a setOccluded:NO];
+  [window_a setOccludedForTesting:NO];
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
   WaitForOcclusionUpdate();
   ASSERT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // Fake the exit transition start.
-  PostNotification(NSWindowWillExitFullScreenNotification, window_a_);
+  PostNotification(NSWindowWillExitFullScreenNotification, window_a);
 
-  [window_a_ setOccludedForTesting:YES];
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  [window_a setOccludedForTesting:YES];
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // End the transition.
-  PostNotification(NSWindowDidExitFullScreenNotification, window_a_);
+  PostNotification(NSWindowDidExitFullScreenNotification, window_a);
 
-  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a_);
+  PostNotification(NSWindowDidChangeOcclusionStateNotification, window_a);
 
   WaitForOcclusionUpdate();
 
@@ -919,7 +918,7 @@
   WebContentsViewCocoa* web_contents_b =
       [[WebContentsViewCocoaForOcclusionTesting alloc]
           initWithFrame:kWebContentsBFrame];
-  [window_a_.contentView addSubview:web_contents_b];
+  [[window_a contentView] addSubview:web_contents_b];
   WebContentsNSViewHostStub host_2;
   [web_contents_b setHost:&host_2];
   host_2.OnWindowVisibilityChanged(remote_cocoa::mojom::Visibility::kVisible);
@@ -928,13 +927,13 @@
   WebContentsViewCocoa* web_contents_c =
       [[WebContentsViewCocoaForOcclusionTesting alloc]
           initWithFrame:kWebContentsCFrame];
-  [window_a_.contentView addSubview:web_contents_c];
+  [[window_a contentView] addSubview:web_contents_c];
   WebContentsNSViewHostStub host_3;
   [web_contents_c setHost:&host_3];
   host_3.OnWindowVisibilityChanged(remote_cocoa::mojom::Visibility::kVisible);
 
   // Add window_b to occlude window_a and its web contentses.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
@@ -945,7 +944,7 @@
             remote_cocoa::mojom::Visibility::kOccluded);
 
   // Close window b, which should expose the web contentses.
-  CloseWindow(window_b_);
+  CloseWindow(window_b);
 
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
@@ -966,20 +965,20 @@
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
-  SetViewHidden(window_a_web_contents_view_cocoa_, YES);
+  SetViewHidden(window_a_web_contents_view_cocoa, YES);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kHidden);
 
-  SetViewHidden(window_a_web_contents_view_cocoa_, NO);
+  SetViewHidden(window_a_web_contents_view_cocoa, NO);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // Hiding the superview should have the same effect.
-  SetViewHidden(window_a_web_contents_view_cocoa_.superview, YES);
+  SetViewHidden([window_a_web_contents_view_cocoa superview], YES);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kHidden);
 
-  SetViewHidden(window_a_web_contents_view_cocoa_.superview, NO);
+  SetViewHidden([window_a_web_contents_view_cocoa superview], NO);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 }
@@ -994,22 +993,23 @@
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
-  RemoveViewFromSuperview(window_a_web_contents_view_cocoa_);
+  RemoveViewFromSuperview(window_a_web_contents_view_cocoa);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kHidden);
 
   // Adding it back should make it visible.
-  AddSubviewOfView(window_a_web_contents_view_cocoa_, window_a_.contentView);
+  AddSubviewOfView(window_a_web_contents_view_cocoa, [window_a contentView]);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
   // Try the same with its superview.
   const NSRect kTmpViewFrame = NSMakeRect(0.0, 0.0, 10.0, 10.0);
-  NSView* tmpView = [[NSView alloc] initWithFrame:kTmpViewFrame];
-  [window_a_.contentView addSubview:tmpView];
-  AddSubviewOfView(tmpView, window_a_.contentView);
-  RemoveViewFromSuperview(window_a_web_contents_view_cocoa_);
-  AddSubviewOfView(window_a_web_contents_view_cocoa_, tmpView);
+  base::scoped_nsobject<NSView> tmpView(
+      [[NSView alloc] initWithFrame:kTmpViewFrame]);
+  [[window_a contentView] addSubview:tmpView];
+  AddSubviewOfView(tmpView, [window_a contentView]);
+  RemoveViewFromSuperview(window_a_web_contents_view_cocoa);
+  AddSubviewOfView(window_a_web_contents_view_cocoa, tmpView);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
@@ -1017,7 +1017,7 @@
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kHidden);
 
-  AddSubviewOfView(tmpView, [window_a_ contentView]);
+  AddSubviewOfView(tmpView, [window_a contentView]);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 }
@@ -1031,15 +1031,15 @@
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
-  MiniaturizeWindow(window_a_);
+  MiniaturizeWindow(window_a);
 
-  EXPECT_TRUE([window_a_ isMiniaturized]);
+  EXPECT_TRUE([window_a isMiniaturized]);
   EXPECT_NE(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 
-  DeminiaturizeWindow(window_a_);
+  DeminiaturizeWindow(window_a);
 
-  EXPECT_FALSE([window_a_ isMiniaturized]);
+  EXPECT_FALSE([window_a isMiniaturized]);
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kVisible);
 }
@@ -1048,7 +1048,7 @@
 // added to or removed from a parent. In Chrome, some webcontents visibility
 // watchers add child windows (bubbles) when visibility changes. We want to
 // avoid the situation where a browser component adds a child window,
-// triggering a visibility update, which causes a visibility watcher to add
+// triggering a visility update, which causes a visibility watcher to add
 // a second child window (while we're still inside AppKit code adding the
 // first).
 IN_PROC_BROWSER_TEST_P(
@@ -1068,14 +1068,14 @@
   // onscreen should not trigger a visibility update (at least not from us).
   // A check inside the webcontents will also ensure no updates occur while
   // the window modifies its child window list.
-  [window_a_ addChildWindow:child_window_web_contents.window
-                    ordered:NSWindowAbove];
+  [window_a addChildWindow:[child_window_web_contents window]
+                   ordered:NSWindowAbove];
 
   EXPECT_FALSE([[NSClassFromString(@"WebContentsOcclusionCheckerMac")
       sharedInstance] occlusionStateUpdatesAreScheduledForTesting]);
 
   // Modify the child window list by removing a child window.
-  [window_a_ removeChildWindow:child_window_web_contents.window];
+  [window_a removeChildWindow:[child_window_web_contents window]];
 
   EXPECT_FALSE([[NSClassFromString(@"WebContentsOcclusionCheckerMac")
       sharedInstance] occlusionStateUpdatesAreScheduledForTesting]);
@@ -1089,7 +1089,7 @@
   InitWindowA();
 
   // Create a second window that occludes window_a.
-  InitWindowB(window_a_.frame);
+  InitWindowB([window_a frame]);
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
             remote_cocoa::mojom::Visibility::kOccluded);
@@ -1097,7 +1097,7 @@
   // Make window_a a child of window_b. The occlusion system ignores
   // child windows, so ensure window_a's occlusion state changes back
   // to visible.
-  [window_b_ addChildWindow:window_a_ ordered:NSWindowAbove];
+  [window_b addChildWindow:window_a ordered:NSWindowAbove];
 
   WaitForOcclusionUpdate();
   EXPECT_EQ(WindowAWebContentsVisibility(),
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 95e0b88..aa0030b 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -121,7 +121,6 @@
     "//components/viz/host",
     "//components/web_package",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/browser/aggregation_service:mojo_bindings",
     "//content/browser/aggregation_service/proto:aggregatable_report_proto",
     "//content/browser/attribution_reporting:attribution_reporting_proto",
diff --git a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
index ad3f571..4df612f 100644
--- a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
+++ b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
@@ -19,10 +19,6 @@
 #include "ui/accessibility/platform/inspect/ax_script_instruction.h"
 #include "url/gurl.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 namespace {
diff --git a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
index d4a0163d..3902856 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
@@ -26,10 +26,6 @@
 #include "ui/accessibility/platform/ax_utils_mac.h"
 #include "url/gurl.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 class BrowserAccessibilityCocoaBrowserTest : public ContentBrowserTest {
@@ -51,7 +47,7 @@
   }
 
   // Trigger a context menu for the provided element without showing it. Returns
-  // the coordinates where the context menu was invoked (calculated based on
+  // the coordinates where the  context menu was invoked (calculated based on
   // the provided element). These coordinates are relative to the RenderView
   // origin.
   gfx::Point TriggerContextMenuAndGetMenuLocation(
@@ -122,8 +118,8 @@
   SimulateKeyPress(shell()->web_contents(), ui::DomKey::FromCharacter('B'),
                    ui::DomCode::US_B, ui::VKEY_B, false, false, false, false);
 
-  BrowserAccessibilityCocoa* cocoa_text_field =
-      text_field->GetNativeViewAccessible();
+  base::scoped_nsobject<BrowserAccessibilityCocoa> cocoa_text_field(
+      [text_field->GetNativeViewAccessible() retain]);
   AccessibilityNotificationWaiter value_waiter(shell()->web_contents(),
                                                ui::kAXModeComplete,
                                                ax::mojom::Event::kValueChanged);
@@ -170,21 +166,22 @@
 
   BrowserAccessibility* table = FindNode(ax::mojom::Role::kTable);
   ASSERT_NE(nullptr, table);
-  BrowserAccessibilityCocoa* cocoa_table = table->GetNativeViewAccessible();
+  base::scoped_nsobject<BrowserAccessibilityCocoa> cocoa_table(
+      [table->GetNativeViewAccessible() retain]);
 
   // Test AXCellForColumnAndRow for four coordinates
   for (unsigned col = 0; col < 2; col++) {
     for (unsigned row = 0; row < 2; row++) {
-      BrowserAccessibilityCocoa* cell =
-          [cocoa_table accessibilityCellForColumn:col row:row];
+      base::scoped_nsobject<BrowserAccessibilityCocoa> cell(
+          [[cocoa_table accessibilityCellForColumn:col row:row] retain]);
 
       // It should be a cell.
-      EXPECT_NSEQ(@"AXCell", cell.accessibilityRole);
+      EXPECT_NSEQ(@"AXCell", [cell accessibilityRole]);
 
       // The column index and row index of the cell should match what we asked
       // for.
-      EXPECT_NSEQ(NSMakeRange(col, 1), cell.accessibilityColumnIndexRange);
-      EXPECT_NSEQ(NSMakeRange(row, 1), cell.accessibilityRowIndexRange);
+      EXPECT_NSEQ(NSMakeRange(col, 1), [cell accessibilityColumnIndexRange]);
+      EXPECT_NSEQ(NSMakeRange(row, 1), [cell accessibilityRowIndexRange]);
     }
   }
 }
@@ -208,7 +205,7 @@
   BrowserAccessibilityCocoa* cocoa_text = text->GetNativeViewAccessible();
   ASSERT_NE(nil, cocoa_text);
 
-  NSPoint position = cocoa_text.position.pointValue;
+  NSPoint position = [[cocoa_text position] pointValue];
 
   NSSize size = cocoa_text.accessibilityFrame.size;
   NSRect frame = NSMakeRect(position.x, position.y, size.width, size.height);
@@ -267,7 +264,7 @@
   content_size.Enlarge(0, dh);
   shell()->ResizeWebContentForTests(content_size);
 
-  NSPoint p0_after = cocoa_text.position.pointValue;
+  NSPoint p0_after = [[cocoa_text position] pointValue];
   NSRect r0_after = [cocoa_text frameForRange:NSMakeRange(0, 5)];
 
   ASSERT_EQ(p0_before.y + dh, p0_after.y);
@@ -405,10 +402,11 @@
   for (int child_index = 0; child_index < child_count; child_index++) {
     BrowserAccessibility* child =
         manager->GetBrowserAccessibilityRoot()->PlatformGetChild(child_index);
-    BrowserAccessibilityCocoa* child_obj = child->GetNativeViewAccessible();
+    base::scoped_nsobject<BrowserAccessibilityCocoa> child_obj(
+        [child->GetNativeViewAccessible() retain]);
 
     EXPECT_NSEQ(base::SysUTF8ToNSString(expected_descriptions[child_index]),
-                child_obj.accessibilityLabel);
+                [child_obj accessibilityLabel]);
   }
 }
 
@@ -492,10 +490,11 @@
 
   BrowserAccessibility* table =
       manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0);
-  BrowserAccessibilityCocoa* table_obj = table->GetNativeViewAccessible();
-  NSArray* row_nodes = table_obj.accessibilityRows;
+  base::scoped_nsobject<BrowserAccessibilityCocoa> table_obj(
+      [table->GetNativeViewAccessible() retain]);
+  NSArray* row_nodes = [table_obj accessibilityRows];
 
-  EXPECT_EQ(3U, row_nodes.count);
+  EXPECT_EQ(3U, [row_nodes count]);
   EXPECT_NSEQ(@"AXRow", [row_nodes[0] role]);
   EXPECT_NSEQ(@"row1", [row_nodes[0] accessibilityLabel]);
 
@@ -542,11 +541,12 @@
 
   BrowserAccessibility* column =
       manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0);
-  BrowserAccessibilityCocoa* col_obj = column->GetNativeViewAccessible();
-  EXPECT_NSEQ(@"AXColumn", col_obj.role);
-  EXPECT_NSEQ(@"column1", col_obj.accessibilityLabel);
+  base::scoped_nsobject<BrowserAccessibilityCocoa> col_obj(
+      [column->GetNativeViewAccessible() retain]);
+  EXPECT_NSEQ(@"AXColumn", [col_obj role]);
+  EXPECT_NSEQ(@"column1", [col_obj accessibilityLabel]);
 
-  NSArray* row_nodes = col_obj.accessibilityRows;
+  NSArray* row_nodes = [col_obj accessibilityRows];
   EXPECT_NSEQ(@"AXRow", [row_nodes[0] role]);
   EXPECT_NSEQ(@"row1", [row_nodes[0] accessibilityLabel]);
 
@@ -586,14 +586,16 @@
   ASSERT_TRUE(waiter.WaitForNotification());
 
   BrowserAccessibility* table = FindNode(ax::mojom::Role::kTable);
-  BrowserAccessibilityCocoa* table_obj = table->GetNativeViewAccessible();
+  base::scoped_nsobject<BrowserAccessibilityCocoa> table_obj(
+      [table->GetNativeViewAccessible() retain]);
 
-  EXPECT_NSEQ(@"AXTable", table_obj.role);
-  EXPECT_NSEQ(@"Population per country", table_obj.accessibilityLabel);
-  BrowserAccessibilityCocoa* table_header = table_obj.header;
+  EXPECT_NSEQ(@"AXTable", [table_obj role]);
+  EXPECT_NSEQ(@"Population per country", [table_obj accessibilityLabel]);
+  base::scoped_nsobject<BrowserAccessibilityCocoa> table_header(
+      [[table_obj header] retain]);
 
-  NSArray* children = table_header.children;
-  EXPECT_EQ(2U, children.count);
+  NSArray* children = [table_header children];
+  EXPECT_EQ(2U, [children count]);
 
   EXPECT_NSEQ(@"AXCell", [children[0] role]);
   EXPECT_NSEQ(@"Country", [children[0] accessibilityLabel]);
@@ -618,9 +620,10 @@
   ASSERT_TRUE(waiter.WaitForNotification());
 
   BrowserAccessibility* tree = FindNode(ax::mojom::Role::kTree);
-  BrowserAccessibilityCocoa* cocoa_tree = tree->GetNativeViewAccessible();
+  base::scoped_nsobject<BrowserAccessibilityCocoa> cocoa_tree(
+      [tree->GetNativeViewAccessible() retain]);
 
-  NSArray* tree_children = cocoa_tree.children;
+  NSArray* tree_children = [cocoa_tree children];
   ASSERT_NSEQ(@"AXRow", [tree_children[0] role]);
   ASSERT_NSEQ(@"AXRow", [tree_children[1] role]);
 
@@ -689,11 +692,11 @@
   };
 
   for (auto& test : tests) {
-    BrowserAccessibilityCocoa* parent =
-        FindNode(test.first)->GetNativeViewAccessible();
-    BrowserAccessibilityCocoa* child = parent.children[1];
+    base::scoped_nsobject<BrowserAccessibilityCocoa> parent(
+        [FindNode(test.first)->GetNativeViewAccessible() retain]);
+    BrowserAccessibilityCocoa* child = [parent children][1];
 
-    EXPECT_NE(nullptr, parent);
+    EXPECT_NE(nullptr, parent.get());
     EXPECT_EQ([child owner], [child actionTarget]);
     EXPECT_EQ([parent owner], [parent actionTarget]);
 
@@ -742,12 +745,12 @@
   };
 
   for (auto& test : tests) {
-    BrowserAccessibilityCocoa* parent =
-        FindNode(test.first)->GetNativeViewAccessible();
-    BrowserAccessibilityCocoa* first_child = parent.children[0];
-    BrowserAccessibilityCocoa* second_child = parent.children[1];
+    base::scoped_nsobject<BrowserAccessibilityCocoa> parent(
+        [FindNode(test.first)->GetNativeViewAccessible() retain]);
+    BrowserAccessibilityCocoa* first_child = [parent children][0];
+    BrowserAccessibilityCocoa* second_child = [parent children][1];
 
-    EXPECT_NE(nullptr, parent);
+    EXPECT_NE(nullptr, parent.get());
     EXPECT_EQ([second_child owner], [second_child actionTarget]);
     EXPECT_EQ(test.second, [second_child owner] == [parent actionTarget]);
 
@@ -776,12 +779,12 @@
   ASSERT_TRUE(NavigateToURL(shell(), url));
   ASSERT_TRUE(waiter.WaitForNotification());
 
-  BrowserAccessibilityCocoa* content_editable =
-      GetManager()
-          ->GetBrowserAccessibilityRoot()
-          ->PlatformGetChild(0)
-          ->GetNativeViewAccessible();
-  EXPECT_EQ(content_editable.children.count, 5ul);
+  base::scoped_nsobject<BrowserAccessibilityCocoa> content_editable(
+      [GetManager()
+              ->GetBrowserAccessibilityRoot()
+              ->PlatformGetChild(0)
+              ->GetNativeViewAccessible() retain]);
+  EXPECT_EQ([[content_editable children] count], 5ul);
 
   WebContents* web_contents = shell()->web_contents();
   auto run_script_and_wait_for_selection_change =
diff --git a/content/browser/accessibility/hit_testing_mac_browsertest.mm b/content/browser/accessibility/hit_testing_mac_browsertest.mm
index b74e8db..754176a 100644
--- a/content/browser/accessibility/hit_testing_mac_browsertest.mm
+++ b/content/browser/accessibility/hit_testing_mac_browsertest.mm
@@ -11,10 +11,6 @@
 #include "content/shell/browser/shell.h"
 #include "ui/gfx/mac/coordinate_conversion.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 #define EXPECT_ACCESSIBILITY_MAC_HIT_TEST_RESULT(css_point, expected_element, \
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index 81568c0..e23223d 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -281,6 +281,11 @@
   // or frame notifications.
   common_string_cache_.clear();
   ResetContentChangedEventsCounter();
+
+  // Turn off accessibility on the renderer side by resetting the AXMode.
+  BrowserAccessibilityStateImpl* accessibility_state =
+      BrowserAccessibilityStateImpl::GetInstance();
+  accessibility_state->ResetAccessibilityMode();
 }
 
 void WebContentsAccessibilityAndroid::ReEnableRendererAccessibility(
@@ -307,6 +312,13 @@
       GetRootBrowserAccessibilityManager();
   DCHECK(root_manager);
   root_manager->set_web_contents_accessibility(GetWeakPtr());
+
+  // The AXMode should have been set when the accessibility state was changed,
+  // so by this method it should be something other than kNone.
+  BrowserAccessibilityStateImpl* accessibility_state =
+      BrowserAccessibilityStateImpl::GetInstance();
+  DCHECK(accessibility_state->GetAccessibilityMode().flags() !=
+         ui::AXMode::kNone);
 }
 
 jboolean WebContentsAccessibilityAndroid::IsRootManagerConnected(JNIEnv* env) {
diff --git a/content/browser/form_controls_browsertest_mac.mm b/content/browser/form_controls_browsertest_mac.mm
index 7d53695b..c869ee4 100644
--- a/content/browser/form_controls_browsertest_mac.mm
+++ b/content/browser/form_controls_browsertest_mac.mm
@@ -4,10 +4,6 @@
 
 #include "content/browser/form_controls_browsertest_mac.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 bool MacOSVersionSupportsDarkMode() {
   if (@available(macOS 10.14, *))
     return true;
diff --git a/content/browser/gpu/browser_child_process_backgrounded_bridge_browsertest.mm b/content/browser/gpu/browser_child_process_backgrounded_bridge_browsertest.mm
index e7a714d5..4a506d2 100644
--- a/content/browser/gpu/browser_child_process_backgrounded_bridge_browsertest.mm
+++ b/content/browser/gpu/browser_child_process_backgrounded_bridge_browsertest.mm
@@ -13,10 +13,6 @@
 #include "content/public/test/content_browser_test.h"
 #include "gpu/config/gpu_finch_features.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 bool IsProcessBackgrounded(base::ProcessId pid) {
diff --git a/content/browser/keyboard_lock_browsertest_ios.mm b/content/browser/keyboard_lock_browsertest_ios.mm
index 33236f3..27d9bd76 100644
--- a/content/browser/keyboard_lock_browsertest_ios.mm
+++ b/content/browser/keyboard_lock_browsertest_ios.mm
@@ -8,10 +8,6 @@
 #include "content/browser/renderer_host/render_widget_host_view_ios.h"
 #include "content/browser/web_contents/web_contents_view_ios.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 namespace {
diff --git a/content/browser/keyboard_lock_browsertest_mac.mm b/content/browser/keyboard_lock_browsertest_mac.mm
index 3e64d1258..afb7697 100644
--- a/content/browser/keyboard_lock_browsertest_mac.mm
+++ b/content/browser/keyboard_lock_browsertest_mac.mm
@@ -8,10 +8,6 @@
 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
 #include "content/browser/web_contents/web_contents_view_mac.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 namespace {
diff --git a/content/browser/pointer_lock_browsertest_ios.mm b/content/browser/pointer_lock_browsertest_ios.mm
index af29b50..fe5e5ce 100644
--- a/content/browser/pointer_lock_browsertest_ios.mm
+++ b/content/browser/pointer_lock_browsertest_ios.mm
@@ -8,10 +8,6 @@
 #include "content/browser/renderer_host/render_widget_host_view_ios.h"
 #include "content/browser/web_contents/web_contents_view_ios.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewIOS {
diff --git a/content/browser/pointer_lock_browsertest_mac.mm b/content/browser/pointer_lock_browsertest_mac.mm
index 969f6cd..3ac35d69 100644
--- a/content/browser/pointer_lock_browsertest_mac.mm
+++ b/content/browser/pointer_lock_browsertest_mac.mm
@@ -8,10 +8,6 @@
 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
 #include "content/browser/web_contents/web_contents_view_mac.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewMac {
diff --git a/content/browser/renderer_host/render_frame_host_impl_mac_browsertest.mm b/content/browser/renderer_host/render_frame_host_impl_mac_browsertest.mm
index d950bc8..283238e 100644
--- a/content/browser/renderer_host/render_frame_host_impl_mac_browsertest.mm
+++ b/content/browser/renderer_host/render_frame_host_impl_mac_browsertest.mm
@@ -4,6 +4,7 @@
 
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 
+#include "base/mac/scoped_nsobject.h"
 #include "base/run_loop.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/web_contents.h"
@@ -15,10 +16,6 @@
 #include "ui/base/cocoa/find_pasteboard.h"
 #include "url/gurl.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 using RenderFrameHostImplBrowserMacTest = ContentBrowserTest;
@@ -31,7 +28,8 @@
   ASSERT_TRUE(NavigateToURL(web_contents, url));
 
   FindPasteboard* pboard = [FindPasteboard sharedInstance];
-  NSString* original_pboard_text = [[pboard findText] copy];
+  base::scoped_nsobject<NSString> original_pboard_text(
+      [[pboard findText] copy]);
 
   [pboard setFindText:@"test"];
   EXPECT_NSEQ(@"test", [pboard findText]);
@@ -44,7 +42,7 @@
   base::RunLoop loop;
   __block base::OnceClosure quit_closure = loop.QuitClosure();
 
-  NSNotificationCenter* center = NSNotificationCenter.defaultCenter;
+  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
   id notification_handle =
       [center addObserverForName:kFindPasteboardChangedNotification
                           object:pboard
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
index 3f524df..d28b3f0 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
@@ -20,10 +20,6 @@
 #include "third_party/blink/public/platform/web_text_input_type.h"
 #include "ui/events/test/cocoa_test_event_utils.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 @interface TextInputFlagChangeWaiter : NSObject
 @end
 
@@ -47,6 +43,7 @@
 
 - (void)dealloc {
   [_rwhv_cocoa removeObserver:self forKeyPath:@"textInputFlags"];
+  [super dealloc];
 }
 
 - (void)reset {
@@ -73,7 +70,7 @@
 
 class TextCallbackWaiter {
  public:
-  TextCallbackWaiter() = default;
+  TextCallbackWaiter() {}
 
   TextCallbackWaiter(const TextCallbackWaiter&) = delete;
   TextCallbackWaiter& operator=(const TextCallbackWaiter&) = delete;
@@ -94,7 +91,7 @@
 
 class TextSelectionWaiter : public TextInputManager::Observer {
  public:
-  explicit TextSelectionWaiter(RenderWidgetHostViewMac* rwhv) {
+  TextSelectionWaiter(RenderWidgetHostViewMac* rwhv) {
     rwhv->GetTextInputManager()->AddObserver(this);
   }
 
@@ -135,7 +132,7 @@
 }
 
 // Test that -firstRectForCharacterRange:actualRange: works when the range
-// isn't in the active selection, which requires a sync IPC to the renderer.
+// isn't in the active selection, which requres a sync IPC to the renderer.
 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewMacTest,
                        GetFirstRectForCharacterRangeUncached) {
   GURL url("data:text/html,Hello");
@@ -171,9 +168,9 @@
   RenderWidgetHostViewMac* rwhv_mac =
       static_cast<RenderWidgetHostViewMac*>(rwhv);
   RenderWidgetHostViewCocoa* rwhv_cocoa = rwhv_mac->GetInProcessNSView();
-  TextInputFlagChangeWaiter* flag_change_waiter =
+  base::scoped_nsobject<TextInputFlagChangeWaiter> flag_change_waiter(
       [[TextInputFlagChangeWaiter alloc]
-          initWithRenderWidgetHostViewCocoa:rwhv_cocoa];
+          initWithRenderWidgetHostViewCocoa:rwhv_cocoa]);
 
   EXPECT_TRUE(ExecJs(shell(), "ta.focus();"));
   [flag_change_waiter wait];
diff --git a/content/browser/scheduler/responsiveness/native_event_observer_browsertest.mm b/content/browser/scheduler/responsiveness/native_event_observer_browsertest.mm
index c9cbb8d..5f484381 100644
--- a/content/browser/scheduler/responsiveness/native_event_observer_browsertest.mm
+++ b/content/browser/scheduler/responsiveness/native_event_observer_browsertest.mm
@@ -12,11 +12,8 @@
 
 #import <Carbon/Carbon.h>
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace content::responsiveness {
+namespace content {
+namespace responsiveness {
 
 namespace {
 
@@ -58,8 +55,9 @@
       kVK_Return, '\r', NSEventTypeKeyDown, 0);
   [NSApp sendEvent:event];
 
-  EXPECT_EQ(observer.will_run_id(), (__bridge void*)event);
-  EXPECT_EQ(observer.did_run_id(), (__bridge void*)event);
+  EXPECT_EQ(observer.will_run_id(), event);
+  EXPECT_EQ(observer.did_run_id(), event);
 }
 
-}  // namespace content::responsiveness
+}  // namespace responsiveness
+}  // namespace content
diff --git a/content/browser/site_per_process_mac_browsertest.mm b/content/browser/site_per_process_mac_browsertest.mm
index ff9c4eb..d813759 100644
--- a/content/browser/site_per_process_mac_browsertest.mm
+++ b/content/browser/site_per_process_mac_browsertest.mm
@@ -22,10 +22,6 @@
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "third_party/ocmock/ocmock_extensions.h"
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace content {
 
 namespace {
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index bc6d25bd..7490e10 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -202,7 +202,6 @@
     "//components/services/filesystem/public/mojom",
     "//components/tracing:startup_tracing",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/common/fetch:fetch_api_request_proto",
     "//content/public/common:interfaces",
     "//content/public/common/zygote:buildflags",
diff --git a/content/content_resources.grd b/content/content_resources.grd
index d843cc53..90e309e2 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 This file specifies resources for user-facing features under /content. Resources
-for developer-facing chrome:// pages should be in dev_ui_content_resources.grd.
+for developer-facing chrome:// pages should be listed in auto-generated .grd
+files hooked up to chrome/browser/resources:dev_ui_paks
 Other resources that belong in this file:
 * Aliased resources (see shared_resources_data_source.cc).
 * (Optional) Resources for non-Android DevUI pages.
diff --git a/content/dev_ui_content_resources.grd b/content/dev_ui_content_resources.grd
deleted file mode 100644
index 80edbff8..0000000
--- a/content/dev_ui_content_resources.grd
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-This file specifies resources for developer-facing chrome:// pages (DevUI pages)
-under /content. This is needed by the Developer WebUI Dynamic Feature Module
-(DevUI DFM) for Android Chrome. See content_resources.grd for more examples of
-files that belong there instead.
--->
-<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
-  <outputs>
-    <output filename="grit/dev_ui_content_resources.h" type="rc_header">
-      <emit emit_type='prepend'></emit>
-    </output>
-    <output filename="dev_ui_content_resources.pak" type="data_package" />
-  </outputs>
-  <translations />
-  <release seq="1">
-    <includes>
-      <!-- TODO(dpapad): Delete this entire file, no longer used. -->
-      <include name="IDR_NETWORK_ERROR_IGNORED" file="browser/resources/net/network_errors_listing.css" type="BINDATA" />
-    </includes>
-  </release>
-</grit>
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java
index 56debb5..ba213b1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java
@@ -8,17 +8,10 @@
 
 /**
  * Helper class that handles the logic and state behind the "Auto Disable" accessibility feature.
- * This class will start a timer with a {@link WAIT_TIME_BEFORE_DISABLING_ACCESSIBILITY_MS} delay.
- * When the timer is up, the class will notify the provided Client that the underlying renderer
- * accessibility engine can be disabled in the C++ code.
- *
  * Clients need to cancel/reset the timer based on their implementation (e.g. on a user action).
- *
  * Only one timer per instance can exist.
  */
 public class AutoDisableAccessibilityHandler {
-    private static final int WAIT_TIME_BEFORE_DISABLING_ACCESSIBILITY_MS = 60 * 1000;
-
     /**
      * Interface for any Client of this handler.
      */
@@ -57,13 +50,6 @@
     }
 
     /**
-     * Starts running the timer for this instance.
-     */
-    public void startDisableTimer() {
-        startDisableTimer(WAIT_TIME_BEFORE_DISABLING_ACCESSIBILITY_MS);
-    }
-
-    /**
      * Cancels the running timer for this instance.
      */
     public void cancelDisableTimer() {
@@ -74,20 +60,10 @@
     }
 
     /**
-     * Resets the running timer for this instance.
-     */
-    public void resetPendingTimer() {
-        if (!mHasPendingTimer) return;
-
-        mClient.getView().removeCallbacks(mRunnable);
-        mClient.getView().postDelayed(mRunnable, WAIT_TIME_BEFORE_DISABLING_ACCESSIBILITY_MS);
-    }
-
-    /**
      * Helper method to notify Client and reset local state when the timer has expired.
      */
     private void notifyDisable() {
         mClient.onDisabled();
         mHasPendingTimer = false;
     }
-}
\ No newline at end of file
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
index 7f08783..6b93df49 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -87,8 +87,6 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.task.AsyncTask;
-import org.chromium.base.task.TaskTraits;
 import org.chromium.build.BuildConfig;
 import org.chromium.content.browser.WindowEventObserver;
 import org.chromium.content.browser.WindowEventObserverManager;
@@ -320,25 +318,16 @@
                 assert ContentFeatureList.isEnabled(
                         ContentFeatureList.AUTO_DISABLE_ACCESSIBILITY_V2)
                     : "Disable was called, but Auto-disable accessibility is not enabled.";
+                TraceEvent.begin(
+                        "WebContentsAccessibilityImpl.AutoDisableAccessibilityHandler.onDisabled");
                 // If the Auto-disable timer has expired, begin disabling the renderer, and clearing
-                // the Java-side caches.
-                // TODO(mschillaci): This will not re-enable for a Blink event. Fix.
-                AsyncTask<Void> autoDisableTask = new AsyncTask<Void>() {
-                    @Override
-                    protected Void doInBackground() {
-                        WebContentsAccessibilityImplJni.get().disableRendererAccessibility(
-                                mNativeObj);
-                        mEventDispatcher.clearQueue();
-                        mNodeInfoCache.clear();
-                        return null;
-                    }
-
-                    @Override
-                    protected void onPostExecute(Void unused) {
-                        mIsCurrentlyAutoDisabled = true;
-                    }
-                };
-                autoDisableTask.executeWithTaskTraits(TaskTraits.BEST_EFFORT);
+                // the Java-side caches. Changing AXModes must be done on the main thread.
+                WebContentsAccessibilityImplJni.get().disableRendererAccessibility(mNativeObj);
+                mEventDispatcher.clearQueue();
+                mNodeInfoCache.clear();
+                mIsCurrentlyAutoDisabled = true;
+                TraceEvent.end(
+                        "WebContentsAccessibilityImpl.AutoDisableAccessibilityHandler.onDisabled");
             }
         });
 
@@ -464,11 +453,6 @@
             mView.post(serviceMaskRunnable);
         }
 
-        // Start the timer to auto-disable accessibility after a period of no usage.
-        if (ContentFeatureList.isEnabled(ContentFeatureList.AUTO_DISABLE_ACCESSIBILITY_V2)) {
-            mAutoDisableAccessibilityHandler.startDisableTimer();
-        }
-
         // Send state values set by embedders to native-side objects.
         refreshNativeState();
 
@@ -661,18 +645,10 @@
                         convertMaskToEventTypes(serviceEventMask));
             }
 
-            // If the auto-disable feature has disabled then re-enabled the renderer multiple times
-            // for this instance, cancel the timer and stop further disables. We do this to prevent
-            // churn and multiple tree constructions when a service has appeared to be disabled
-            // multiple times then re-enabled. This may happen from the user toggling the service,
-            // or an inaccurate heuristic disabling accessibility prematurely.
-            //
-            // If no accessibility services are enabled, cancel the timer and disable the
-            // renderer after a short delay.
-            //
-            // When any accessibility service is detected:
-            //   * If any accessibility tool is present, cancel the timer.
-            //   * If no accessibility tools are present, begin auto-disable the timer.
+            // If the auto-disable feature is enabled, then we will disable renderer accessibility
+            // and tear down objects when no accessibility services are running. If we have
+            // disabled then re-enabled the renderer multiple times for this instance, then we
+            // will return early and keep accessibility enabled to prevent further churn.
             if (ContentFeatureList.isEnabled(ContentFeatureList.AUTO_DISABLE_ACCESSIBILITY_V2)) {
                 if (mAutoDisableUsageCounter >= AUTO_DISABLE_SINGLE_INSTANCE_TOGGLE_LIMIT) {
                     mAutoDisableAccessibilityHandler.cancelDisableTimer();
@@ -683,23 +659,11 @@
                     mAutoDisableAccessibilityHandler.cancelDisableTimer();
                     mAutoDisableAccessibilityHandler.startDisableTimer(
                             NO_ACCESSIBILITY_SERVICES_ENABLED_DELAY_MS);
-                    return;
-                }
-
-                if (AccessibilityState.isAccessibilityToolPresent()) {
-                    mAutoDisableAccessibilityHandler.cancelDisableTimer();
-                } else {
-                    mAutoDisableAccessibilityHandler.startDisableTimer();
                 }
             }
         }
     }
 
-    private void resetAutoDisableTimer() {
-        if (!ContentFeatureList.isEnabled(ContentFeatureList.AUTO_DISABLE_ACCESSIBILITY_V2)) return;
-        mAutoDisableAccessibilityHandler.resetPendingTimer();
-    }
-
     // AccessibilityNodeProvider
 
     @Override
@@ -727,10 +691,12 @@
         // This must be done before we try to verify/reconnect the root manager, since doing so
         // requires a reference to the webContents.
         if (mIsCurrentlyAutoDisabled) {
+            TraceEvent.begin("WebContentsAccessibilityImpl.reEnableRendererAccessibility");
             WebContentsAccessibilityImplJni.get().reEnableRendererAccessibility(
                     mNativeObj, mDelegate.getWebContents());
             mIsCurrentlyAutoDisabled = false;
             mAutoDisableUsageCounter++;
+            TraceEvent.end("WebContentsAccessibilityImpl.reEnableRendererAccessibility");
         }
 
         if (!isNativeInitialized()) {
@@ -957,8 +923,6 @@
 
     @Override
     public boolean performAction(int virtualViewId, int action, Bundle arguments) {
-        resetAutoDisableTimer();
-
         // We don't support any actions on the host view or nodes
         // that are not (any longer) in the tree.
         if (!isAccessibilityEnabled() || shouldPreventNativeEngineUse()
@@ -1779,7 +1743,6 @@
             mHistogramRecorder.incrementDispatchedEvents();
             if (mTracker != null) mTracker.addEvent(event);
             try {
-                resetAutoDisableTimer();
                 mView.getParent().requestSendAccessibilityEvent(mView, event);
             } catch (IllegalStateException ignored) {
                 // During boot-up of some content shell tests, events will erroneously be sent even
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn
index c901125..23b3e99 100644
--- a/content/public/test/android/BUILD.gn
+++ b/content/public/test/android/BUILD.gn
@@ -28,7 +28,6 @@
     "//content/public/android:content_java",
     "//mojo/public/java:bindings_java",
     "//net/android:net_java",
-    "//net/android:net_java_test_support",
     "//services/service_manager/public/java:service_manager_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_monitor_java",
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java
index 0d75655..6c3d062e 100644
--- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java
+++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java
@@ -10,7 +10,6 @@
 
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.SkipCheck;
-import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.ui.test.util.DeviceRestrictionSkipCheck;
 import org.chromium.ui.test.util.UiDisableIfSkipCheck;
 import org.chromium.ui.test.util.UiRestrictionSkipCheck;
@@ -21,13 +20,6 @@
  * A custom runner for //content JUnit4 tests.
  */
 public class ContentJUnit4ClassRunner extends BaseJUnit4ClassRunner {
-    static {
-        // Always try to add the testing HTTPS root to the cert verifier. We do this here because we
-        // need this to happen before the native code loads the user-added roots, and this is the
-        // safest place to put it.
-        EmbeddedTestServer.initTestCerts();
-    }
-
     /**
      * Create a ContentJUnit4ClassRunner to run {@code klass} and initialize values
      *
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 487c06d..8177e8f 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -200,6 +200,10 @@
     ]
   }
 
+  if (is_apple) {
+    configs += [ "//build/config/compiler:enable_arc" ]
+  }
+
   if (is_mac) {
     sources += [
       "renderer_main_platform_delegate_mac.mm",
@@ -251,7 +255,6 @@
     "//components/viz/client",
     "//components/viz/common",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/child",
     "//content/common",
     "//content/common:buildflags",
diff --git a/content/renderer/render_view_browsertest_mac.mm b/content/renderer/render_view_browsertest_mac.mm
index 8d5f328..fbdd782 100644
--- a/content/renderer/render_view_browsertest_mac.mm
+++ b/content/renderer/render_view_browsertest_mac.mm
@@ -18,10 +18,6 @@
 #include <Carbon/Carbon.h>  // for the kVK_* constants.
 #include <Cocoa/Cocoa.h>
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 using blink::TestWebFrameContentDumper;
 
 namespace content {
diff --git a/content/renderer/renderer_main_platform_delegate_ios.mm b/content/renderer/renderer_main_platform_delegate_ios.mm
index 781850a..1effd368 100644
--- a/content/renderer/renderer_main_platform_delegate_ios.mm
+++ b/content/renderer/renderer_main_platform_delegate_ios.mm
@@ -4,12 +4,16 @@
 
 #include "content/renderer/renderer_main_platform_delegate.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace content {
 
 RendererMainPlatformDelegate::RendererMainPlatformDelegate(
     const MainFunctionParams& parameters) {}
 
-RendererMainPlatformDelegate::~RendererMainPlatformDelegate() {}
+RendererMainPlatformDelegate::~RendererMainPlatformDelegate() = default;
 
 void RendererMainPlatformDelegate::PlatformInitialize() {}
 
diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm
index add9345..22c7e07 100644
--- a/content/renderer/renderer_main_platform_delegate_mac.mm
+++ b/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -14,6 +14,10 @@
 CGError CGSSetDenyWindowServerConnections(bool);
 }
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace content {
 
 namespace {
@@ -37,8 +41,7 @@
 RendererMainPlatformDelegate::RendererMainPlatformDelegate(
     const MainFunctionParams& parameters) {}
 
-RendererMainPlatformDelegate::~RendererMainPlatformDelegate() {
-}
+RendererMainPlatformDelegate::~RendererMainPlatformDelegate() = default;
 
 // TODO(mac-port): Any code needed to initialize a process for purposes of
 // running a renderer needs to also be reflected in chrome_main.cc for
diff --git a/content/renderer/theme_helper_mac.mm b/content/renderer/theme_helper_mac.mm
index 2f77943c..55ef23ba 100644
--- a/content/renderer/theme_helper_mac.mm
+++ b/content/renderer/theme_helper_mac.mm
@@ -8,6 +8,10 @@
 
 #include "base/strings/sys_string_conversions.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 extern "C" {
 bool CGFontRenderingGetFontSmoothingDisabled(void) API_AVAILABLE(macos(10.14));
 }
@@ -15,7 +19,7 @@
 namespace content {
 
 void SystemColorsDidChange(int aqua_color_variant) {
-  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+  NSUserDefaults* defaults = NSUserDefaults.standardUserDefaults;
 
   // Register the defaults in the NSArgumentDomain, which is considered
   // volatile. Registering in the normal application domain fails from within
@@ -30,7 +34,7 @@
 }
 
 bool IsSubpixelAntialiasingAvailable() {
-  if (__builtin_available(macOS 10.14, *)) {
+  if (@available(macOS 10.14, *)) {
     // See https://trac.webkit.org/changeset/239306/webkit for more info.
     return !CGFontRenderingGetFontSmoothingDisabled();
   }
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index feebdb8..5059ffb 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -287,7 +287,6 @@
     "//components/variations/service",
     "//components/web_cache/renderer",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/common:main_frame_counter",
     "//content/public/common",
     "//content/test:content_test_mojo_bindings",
@@ -478,7 +477,6 @@
     "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
     "$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/content/gpu_resources.pak",
     "$root_gen_dir/content/histograms_resources.pak",
     "$root_gen_dir/content/process_resources.pak",
@@ -504,7 +502,6 @@
     ":resources",
     "//base/tracing/protos:chrome_track_event_resources",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/browser/resources:resources",
     "//content/browser/resources/media:resources",
     "//content/browser/webrtc/resources",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 215ca0b..ff91caa 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1608,7 +1608,6 @@
     ":test_interfaces",
     ":web_ui_mojo_test_resources",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
   ]
 
   deps = [
@@ -1998,10 +1997,6 @@
     ]
   }
 
-  if (is_apple) {
-    configs += [ "//build/config/compiler:enable_arc" ]
-  }
-
   if (is_mac) {
     sources += [
       "../browser/accessibility/ax_tree_formatter_mac_browsertest.mm",
@@ -2794,10 +2789,7 @@
 
   configs += [ "//build/config:precompiled_headers" ]
 
-  public_deps = [
-    "//content:content_resources",
-    "//content:dev_ui_content_resources",
-  ]
+  public_deps = [ "//content:content_resources" ]
 
   deps = [
     ":content_test_mojo_bindings",
diff --git a/device/BUILD.gn b/device/BUILD.gn
index 44d174a..2cd70af7 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -18,6 +18,32 @@
 
 is_linux_without_udev = (is_linux || is_chromeos) && !use_udev
 
+if (is_mac) {
+  # TODO(https://crbug.com/1280317): Merge back into device_unittests once all
+  # .mm files are ARCed.
+  source_set("device_unittests_arc") {
+    testonly = true
+    sources = [
+      "fido/mac/authenticator_unittest.mm",
+      "fido/mac/browsing_data_deletion_unittest.mm",
+      "fido/mac/credential_store_unittest.mm",
+      "fido/mac/get_assertion_operation_unittest_mac.mm",
+      "fido/mac/make_credential_operation_unittest_mac.mm",
+    ]
+    configs += [ "//build/config/compiler:enable_arc" ]
+    deps = [
+      "//base/test:test_support",
+      "//device/base:base",
+      "//device/fido",
+      "//device/fido:mocks",
+      "//device/fido:test_support",
+      "//services/data_decoder/public/cpp:test_support",
+    ]
+
+    data_deps = [ "fido/strings:fido_test_strings" ]
+  }
+}
+
 test("device_unittests") {
   sources = [
     "base/synchronization/one_writer_seqlock_unittest.cc",
@@ -142,6 +168,10 @@
     "//url",
   ]
 
+  if (is_mac) {
+    deps += [ ":device_unittests_arc" ]
+  }
+
   data_deps = [
     "bluetooth/strings:bluetooth_test_strings",
     "//testing/buildbot/filters:device_unittests_filters",
@@ -207,12 +237,9 @@
 
   if (is_mac) {
     sources += [
-      "fido/mac/authenticator_unittest.mm",
-      "fido/mac/browsing_data_deletion_unittest.mm",
+      # TODO(https://crbug.com/1280317): Put the fido/mac/*.mm files from
+      # device_unittests_arc back here.
       "fido/mac/credential_metadata_unittest.cc",
-      "fido/mac/credential_store_unittest.mm",
-      "fido/mac/get_assertion_operation_unittest_mac.mm",
-      "fido/mac/make_credential_operation_unittest_mac.mm",
       "fido/mac/util_unittest.cc",
     ]
   }
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index 760da1e..905426a 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -244,6 +244,8 @@
       "LocalAuthentication.framework",
       "Security.framework",
     ]
+
+    configs += [ "//build/config/compiler:enable_arc" ]
   }
 
   if (is_win) {
@@ -452,5 +454,7 @@
       "mac/scoped_touch_id_test_environment.h",
       "mac/scoped_touch_id_test_environment.mm",
     ]
+
+    configs += [ "//build/config/compiler:enable_arc" ]
   }
 }
diff --git a/device/fido/mac/authenticator.mm b/device/fido/mac/authenticator.mm
index 8fdb930..333d5e6 100644
--- a/device/fido/mac/authenticator.mm
+++ b/device/fido/mac/authenticator.mm
@@ -28,6 +28,10 @@
 #include "device/fido/public_key_credential_user_entity.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device::fido::mac {
 
 // static
diff --git a/device/fido/mac/authenticator_config.h b/device/fido/mac/authenticator_config.h
index 7db4c37..d09c789 100644
--- a/device/fido/mac/authenticator_config.h
+++ b/device/fido/mac/authenticator_config.h
@@ -9,9 +9,7 @@
 
 #include "base/component_export.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 struct COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorConfig {
   // The keychain-access-group value used for WebAuthn credentials
@@ -25,8 +23,6 @@
   std::string metadata_secret;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_AUTHENTICATOR_CONFIG_H_
diff --git a/device/fido/mac/authenticator_unittest.mm b/device/fido/mac/authenticator_unittest.mm
index b4b7e99..a4b830d 100644
--- a/device/fido/mac/authenticator_unittest.mm
+++ b/device/fido/mac/authenticator_unittest.mm
@@ -20,6 +20,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device {
 
 namespace {
diff --git a/device/fido/mac/browsing_data_deletion_unittest.mm b/device/fido/mac/browsing_data_deletion_unittest.mm
index a5f1973..5f32c181 100644
--- a/device/fido/mac/browsing_data_deletion_unittest.mm
+++ b/device/fido/mac/browsing_data_deletion_unittest.mm
@@ -4,6 +4,7 @@
 
 #include "device/fido/mac/credential_store.h"
 
+#include <CoreFoundation/CoreFoundation.h>
 #include <Foundation/Foundation.h>
 #include <Security/Security.h>
 
@@ -23,13 +24,17 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 extern "C" {
 // This is a private Security Framework symbol. It indicates that a query must
 // be run on the "syncable" macOS keychain, which is where Secure Enclave keys
 // are stored. This test needs it because it tries to erase all credentials
 // belonging to the (test-only) keychain access group, and the corresponding
 // filter label (kSecAttrAccessGroup) appears to be ineffective *unless*
-// kSecAttrNoLegacy is `@YES`.
+// kSecAttrNoLegacy is `kCFBooleanTrue`.
 extern const CFStringRef kSecAttrNoLegacy;
 }
 
@@ -37,8 +42,7 @@
 
 using test::TestCallbackReceiver;
 
-namespace fido {
-namespace mac {
+namespace fido::mac {
 namespace {
 
 constexpr char kKeychainAccessGroup[] =
@@ -60,8 +64,8 @@
   base::ScopedCFTypeRef<CFStringRef> access_group_ref(
       base::SysUTF8ToCFStringRef(kKeychainAccessGroup));
   CFDictionarySetValue(query, kSecAttrAccessGroup, access_group_ref);
-  CFDictionarySetValue(query, kSecAttrNoLegacy, @YES);
-  CFDictionarySetValue(query, kSecReturnAttributes, @YES);
+  CFDictionarySetValue(query, kSecAttrNoLegacy, kCFBooleanTrue);
+  CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
   CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
   return query;
 }
@@ -200,6 +204,7 @@
 }
 
 }  // namespace
-}  // namespace mac
-}  // namespace fido
+
+}  // namespace fido::mac
+
 }  // namespace device
diff --git a/device/fido/mac/credential_metadata.cc b/device/fido/mac/credential_metadata.cc
index e6dfa95..f47d2c5 100644
--- a/device/fido/mac/credential_metadata.cc
+++ b/device/fido/mac/credential_metadata.cc
@@ -18,9 +18,7 @@
 #include "third_party/boringssl/src/include/openssl/hkdf.h"
 #include "third_party/boringssl/src/include/openssl/rand.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 static constexpr size_t kNonceLength = 12;
 
@@ -524,6 +522,4 @@
   return result;
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/credential_metadata.h b/device/fido/mac/credential_metadata.h
index 2a618bb..41affbe 100644
--- a/device/fido/mac/credential_metadata.h
+++ b/device/fido/mac/credential_metadata.h
@@ -26,8 +26,7 @@
 
 class PublicKeyCredentialUserEntity;
 
-namespace fido {
-namespace mac {
+namespace fido::mac {
 
 // CredentialMetadata is the metadata for a Touch ID credential.
 //
@@ -196,8 +195,8 @@
     const std::string& user_display_name,
     bool is_resident);
 
-}  // namespace mac
-}  // namespace fido
+}  // namespace fido::mac
+
 }  // namespace device
 
 #endif  // DEVICE_FIDO_MAC_CREDENTIAL_METADATA_H_
diff --git a/device/fido/mac/credential_metadata_unittest.cc b/device/fido/mac/credential_metadata_unittest.cc
index be86d5c6..ebabddd 100644
--- a/device/fido/mac/credential_metadata_unittest.cc
+++ b/device/fido/mac/credential_metadata_unittest.cc
@@ -9,9 +9,7 @@
 #include "device/fido/public_key_credential_user_entity.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 namespace {
 
 bool MetadataEq(const CredentialMetadata& lhs, const CredentialMetadata& rhs) {
@@ -199,6 +197,4 @@
 }
 
 }  // namespace
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/credential_store.mm b/device/fido/mac/credential_store.mm
index 1798b7c..cd5c1783 100644
--- a/device/fido/mac/credential_store.mm
+++ b/device/fido/mac/credential_store.mm
@@ -4,6 +4,7 @@
 
 #include "device/fido/mac/credential_store.h"
 
+#include <CoreFoundation/CoreFoundation.h>
 #import <Foundation/Foundation.h>
 #import <LocalAuthentication/LocalAuthentication.h>
 #import <Security/Security.h>
@@ -12,10 +13,10 @@
 #include "base/containers/cxx20_erase.h"
 #include "base/feature_list.h"
 #include "base/logging.h"
+#include "base/mac/bridging.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_logging.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/sys_string_conversions.h"
@@ -28,6 +29,10 @@
 #include "device/fido/mac/touch_id_context.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device::fido::mac {
 
 namespace {
@@ -43,12 +48,13 @@
       kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
       &kCFTypeDictionaryValueCallBacks));
   CFDictionarySetValue(query, kSecClass, kSecClassKey);
-  CFDictionarySetValue(query, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(config.keychain_access_group));
+  CFDictionarySetValue(
+      query, kSecAttrAccessGroup,
+      base::SysUTF8ToCFStringRef(config.keychain_access_group));
   if (rp_id) {
     CFDictionarySetValue(
         query, kSecAttrLabel,
-        base::SysUTF8ToNSString(EncodeRpId(config.metadata_secret, *rp_id)));
+        base::SysUTF8ToCFStringRef(EncodeRpId(config.metadata_secret, *rp_id)));
   }
   return query;
 }
@@ -93,11 +99,11 @@
       &kCFTypeDictionaryValueCallBacks));
   CFDictionarySetValue(query, kSecClass, kSecClassKey);
   CFDictionarySetValue(query, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(keychain_access_group));
+                       base::SysUTF8ToCFStringRef(keychain_access_group));
   CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
   // Return the key reference and its attributes.
-  CFDictionarySetValue(query, kSecReturnRef, @YES);
-  CFDictionarySetValue(query, kSecReturnAttributes, @YES);
+  CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
+  CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
 
   base::ScopedCFTypeRef<CFArrayRef> keychain_items;
   {
@@ -196,7 +202,7 @@
 }
 
 struct TouchIdCredentialStore::ObjCStorage {
-  base::scoped_nsobject<LAContext> authentication_context_;
+  LAContext* __strong authentication_context_;
 };
 
 TouchIdCredentialStore::TouchIdCredentialStore(AuthenticatorConfig config)
@@ -206,7 +212,7 @@
 
 void TouchIdCredentialStore::SetAuthenticationContext(
     LAContext* authentication_context) {
-  objc_storage_->authentication_context_.reset([authentication_context retain]);
+  objc_storage_->authentication_context_ = authentication_context;
 }
 
 absl::optional<std::pair<Credential, base::ScopedCFTypeRef<SecKeyRef>>>
@@ -218,35 +224,39 @@
       CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                 &kCFTypeDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks));
-  CFDictionarySetValue(params, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(config_.keychain_access_group));
+  CFDictionarySetValue(
+      params, kSecAttrAccessGroup,
+      base::SysUTF8ToCFStringRef(config_.keychain_access_group));
   CFDictionarySetValue(params, kSecAttrKeyType,
                        kSecAttrKeyTypeECSECPrimeRandom);
-  CFDictionarySetValue(params, kSecAttrKeySizeInBits, @256);
-  CFDictionarySetValue(params, kSecAttrSynchronizable, @NO);
+  CFDictionarySetValue(params, kSecAttrKeySizeInBits,
+                       base::mac::NSToCFPtrCast(@256));
+  CFDictionarySetValue(params, kSecAttrSynchronizable, kCFBooleanFalse);
   CFDictionarySetValue(params, kSecAttrTokenID, kSecAttrTokenIDSecureEnclave);
 
   CFDictionarySetValue(
       params, kSecAttrLabel,
-      base::SysUTF8ToNSString(EncodeRpId(config_.metadata_secret, rp_id)));
+      base::SysUTF8ToCFStringRef(EncodeRpId(config_.metadata_secret, rp_id)));
   auto credential_metadata =
       CredentialMetadata::FromPublicKeyCredentialUserEntity(
           user, discoverable == kDiscoverable);
   const std::vector<uint8_t> sealed_metadata = SealCredentialMetadata(
       config_.metadata_secret, rp_id, credential_metadata);
-  CFDictionarySetValue(params, kSecAttrApplicationTag,
-                       [NSData dataWithBytes:sealed_metadata.data()
-                                      length:sealed_metadata.size()]);
+  CFDictionarySetValue(
+      params, kSecAttrApplicationTag,
+      base::mac::NSToCFPtrCast([NSData dataWithBytes:sealed_metadata.data()
+                                              length:sealed_metadata.size()]));
   const std::vector<uint8_t> credential_id = GenerateRandomCredentialId();
-  CFDictionarySetValue(params, kSecAttrApplicationLabel,
-                       [NSData dataWithBytes:credential_id.data()
-                                      length:credential_id.size()]);
+  CFDictionarySetValue(
+      params, kSecAttrApplicationLabel,
+      base::mac::NSToCFPtrCast([NSData dataWithBytes:credential_id.data()
+                                              length:credential_id.size()]));
   base::ScopedCFTypeRef<CFMutableDictionaryRef> private_key_params(
       CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                 &kCFTypeDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks));
   CFDictionarySetValue(params, kSecPrivateKeyAttrs, private_key_params);
-  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent, @YES);
+  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent, kCFBooleanTrue);
   // The credential can only be used for signing, and the device needs to be in
   // an unlocked state.
   auto flags =
@@ -260,8 +270,9 @@
   CFDictionarySetValue(private_key_params, kSecAttrAccessControl,
                        access_control);
   if (objc_storage_->authentication_context_) {
-    CFDictionarySetValue(private_key_params, kSecUseAuthenticationContext,
-                         objc_storage_->authentication_context_);
+    CFDictionarySetValue(
+        private_key_params, kSecUseAuthenticationContext,
+        (__bridge CFTypeRef)objc_storage_->authentication_context_);
   }
   base::ScopedCFTypeRef<CFErrorRef> cferr;
   base::ScopedCFTypeRef<SecKeyRef> private_key =
@@ -306,29 +317,32 @@
       CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                 &kCFTypeDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks));
-  CFDictionarySetValue(params, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(config_.keychain_access_group));
+  CFDictionarySetValue(
+      params, kSecAttrAccessGroup,
+      base::SysUTF8ToCFStringRef(config_.keychain_access_group));
   CFDictionarySetValue(params, kSecAttrKeyType,
                        kSecAttrKeyTypeECSECPrimeRandom);
-  CFDictionarySetValue(params, kSecAttrKeySizeInBits, @256);
-  CFDictionarySetValue(params, kSecAttrSynchronizable, @NO);
+  CFDictionarySetValue(params, kSecAttrKeySizeInBits,
+                       base::mac::NSToCFPtrCast(@256));
+  CFDictionarySetValue(params, kSecAttrSynchronizable, kCFBooleanFalse);
   CFDictionarySetValue(params, kSecAttrTokenID, kSecAttrTokenIDSecureEnclave);
 
   CFDictionarySetValue(
       params, kSecAttrLabel,
-      base::SysUTF8ToNSString(EncodeRpId(config_.metadata_secret, rp_id)));
+      base::SysUTF8ToCFStringRef(EncodeRpId(config_.metadata_secret, rp_id)));
   CFDictionarySetValue(params, kSecAttrApplicationTag,
-                       base::SysUTF8ToNSString(EncodeRpIdAndUserIdDeprecated(
+                       base::SysUTF8ToCFStringRef(EncodeRpIdAndUserIdDeprecated(
                            config_.metadata_secret, rp_id, user.id)));
-  CFDictionarySetValue(params, kSecAttrApplicationLabel,
-                       [NSData dataWithBytes:credential_id.data()
-                                      length:credential_id.size()]);
+  CFDictionarySetValue(
+      params, kSecAttrApplicationLabel,
+      base::mac::NSToCFPtrCast([NSData dataWithBytes:credential_id.data()
+                                              length:credential_id.size()]));
   base::ScopedCFTypeRef<CFMutableDictionaryRef> private_key_params(
       CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                 &kCFTypeDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks));
   CFDictionarySetValue(params, kSecPrivateKeyAttrs, private_key_params);
-  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent, @YES);
+  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent, kCFBooleanTrue);
   // Credential can only be used when the device is unlocked. Private key is
   // available for signing after user authorization with biometrics or
   // password.
@@ -340,8 +354,9 @@
   CFDictionarySetValue(private_key_params, kSecAttrAccessControl,
                        access_control);
   if (objc_storage_->authentication_context_) {
-    CFDictionarySetValue(private_key_params, kSecUseAuthenticationContext,
-                         objc_storage_->authentication_context_);
+    CFDictionarySetValue(
+        private_key_params, kSecUseAuthenticationContext,
+        (__bridge CFTypeRef)objc_storage_->authentication_context_);
   }
   base::ScopedCFTypeRef<CFErrorRef> cferr;
   base::ScopedCFTypeRef<SecKeyRef> private_key =
@@ -503,11 +518,12 @@
   base::ScopedCFTypeRef<CFMutableDictionaryRef> query =
       DefaultKeychainQuery(config_, rp_id);
   if (objc_storage_->authentication_context_) {
-    CFDictionarySetValue(query, kSecUseAuthenticationContext,
-                         objc_storage_->authentication_context_);
+    CFDictionarySetValue(
+        query, kSecUseAuthenticationContext,
+        (__bridge CFTypeRef)objc_storage_->authentication_context_);
   }
-  CFDictionarySetValue(query, kSecReturnRef, @YES);
-  CFDictionarySetValue(query, kSecReturnAttributes, @YES);
+  CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
+  CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
   CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
 
   base::ScopedCFTypeRef<CFArrayRef> keychain_items;
@@ -632,12 +648,14 @@
   base::ScopedCFTypeRef<CFMutableDictionaryRef> query(CFDictionaryCreateMutable(
       kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
       &kCFTypeDictionaryValueCallBacks));
-  CFDictionarySetValue(query, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(config_.keychain_access_group));
+  CFDictionarySetValue(
+      query, kSecAttrAccessGroup,
+      base::SysUTF8ToCFStringRef(config_.keychain_access_group));
   CFDictionarySetValue(query, kSecClass, kSecClassKey);
-  CFDictionarySetValue(query, kSecAttrApplicationLabel,
-                       [NSData dataWithBytes:credential_id.data()
-                                      length:credential_id.size()]);
+  CFDictionarySetValue(
+      query, kSecAttrApplicationLabel,
+      base::mac::NSToCFPtrCast([NSData dataWithBytes:credential_id.data()
+                                              length:credential_id.size()]));
   OSStatus status = Keychain::GetInstance().ItemDelete(query);
   if (status != errSecSuccess) {
     OSSTATUS_DLOG(ERROR, status) << "SecItemDelete failed";
@@ -678,8 +696,9 @@
       std::vector<uint8_t> sealed_metadata = SealCredentialMetadata(
           config_.metadata_secret, credential.rp_id, credential.metadata);
       CFDictionarySetValue(params, kSecAttrApplicationTag,
-                           [NSData dataWithBytes:sealed_metadata.data()
-                                          length:sealed_metadata.size()]);
+                           base::mac::NSToCFPtrCast([NSData
+                               dataWithBytes:sealed_metadata.data()
+                                      length:sealed_metadata.size()]));
       found_credential = true;
       break;
     }
@@ -693,12 +712,14 @@
   base::ScopedCFTypeRef<CFMutableDictionaryRef> query(CFDictionaryCreateMutable(
       kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
       &kCFTypeDictionaryValueCallBacks));
-  CFDictionarySetValue(query, kSecAttrAccessGroup,
-                       base::SysUTF8ToNSString(config_.keychain_access_group));
+  CFDictionarySetValue(
+      query, kSecAttrAccessGroup,
+      base::SysUTF8ToCFStringRef(config_.keychain_access_group));
   CFDictionarySetValue(query, kSecClass, kSecClassKey);
-  CFDictionarySetValue(query, kSecAttrApplicationLabel,
-                       [NSData dataWithBytes:credential_id.data()
-                                      length:credential_id.size()]);
+  CFDictionarySetValue(
+      query, kSecAttrApplicationLabel,
+      base::mac::NSToCFPtrCast([NSData dataWithBytes:credential_id.data()
+                                              length:credential_id.size()]));
   OSStatus status = Keychain::GetInstance().ItemUpdate(query, params);
   if (status != errSecSuccess) {
     OSSTATUS_DLOG(ERROR, status) << "SecItemUpdate failed";
diff --git a/device/fido/mac/credential_store_unittest.mm b/device/fido/mac/credential_store_unittest.mm
index bf0a87f..5c72d0b 100644
--- a/device/fido/mac/credential_store_unittest.mm
+++ b/device/fido/mac/credential_store_unittest.mm
@@ -15,6 +15,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device::fido::mac {
 namespace {
 
diff --git a/device/fido/mac/discovery.cc b/device/fido/mac/discovery.cc
index c8c89024..129ffedf 100644
--- a/device/fido/mac/discovery.cc
+++ b/device/fido/mac/discovery.cc
@@ -7,9 +7,7 @@
 #include "base/functional/bind.h"
 #include "device/fido/mac/authenticator.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 FidoTouchIdDiscovery::FidoTouchIdDiscovery(
     AuthenticatorConfig authenticator_config)
@@ -40,6 +38,4 @@
   observer()->DiscoveryStarted(this, /*success=*/true, {authenticator_.get()});
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/discovery.h b/device/fido/mac/discovery.h
index 724d6db..2bdefdd 100644
--- a/device/fido/mac/discovery.h
+++ b/device/fido/mac/discovery.h
@@ -12,9 +12,7 @@
 #include "device/fido/fido_discovery_base.h"
 #include "device/fido/mac/authenticator_config.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 class TouchIdAuthenticator;
 
@@ -36,8 +34,6 @@
   base::WeakPtrFactory<FidoTouchIdDiscovery> weak_factory_;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_DISCOVERY_H_
diff --git a/device/fido/mac/fake_keychain.h b/device/fido/mac/fake_keychain.h
index fc60e2f..37ec7ae 100644
--- a/device/fido/mac/fake_keychain.h
+++ b/device/fido/mac/fake_keychain.h
@@ -14,9 +14,7 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "device/fido/mac/keychain.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 // FakeKeychain is an implementation of the Keychain API for testing. It works
 // around behavior that can't be relied on in tests, such as writing to the
@@ -55,8 +53,6 @@
   ~ScopedFakeKeychain() override;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_FAKE_KEYCHAIN_H_
diff --git a/device/fido/mac/fake_keychain.mm b/device/fido/mac/fake_keychain.mm
index ea8472f8..c906f097 100644
--- a/device/fido/mac/fake_keychain.mm
+++ b/device/fido/mac/fake_keychain.mm
@@ -4,8 +4,10 @@
 
 #include "device/fido/mac/fake_keychain.h"
 
+#include <CoreFoundation/CoreFoundation.h>
 #import <Foundation/Foundation.h>
 #import <Security/Security.h>
+#include "base/strings/sys_string_conversions.h"
 
 #if defined(LEAK_SANITIZER)
 #include <sanitizer/lsan_interface.h>
@@ -17,16 +19,15 @@
 #include "device/fido/mac/credential_store.h"
 #include "device/fido/mac/keychain.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 FakeKeychain::FakeKeychain(const std::string& keychain_access_group)
-    : Keychain(),
-      keychain_access_group_(
-          CFStringCreateWithCString(kCFAllocatorDefault,
-                                    keychain_access_group.data(),
-                                    kCFStringEncodingUTF8)) {}
+    : keychain_access_group_(
+          base::SysUTF8ToCFStringRef(keychain_access_group)) {}
 FakeKeychain::~FakeKeychain() {
   // Avoid shutdown leak of error string in Security.framework.
   // See https://github.com/apple-oss-distributions/Security/blob/Security-60158.140.3/OSX/libsecurity_keychain/lib/SecBase.cpp#L88
@@ -73,8 +74,9 @@
               params_copy, kSecPrivateKeyAttrs)));
   DCHECK(CFEqual(base::mac::GetValueFromDictionary<CFBooleanRef>(
                      private_key_params, kSecAttrIsPermanent),
-                 @YES));
-  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent, @NO);
+                 kCFBooleanTrue));
+  CFDictionarySetValue(private_key_params, kSecAttrIsPermanent,
+                       kCFBooleanFalse);
   CFDictionaryRemoveValue(private_key_params, kSecAttrAccessControl);
   CFDictionaryRemoveValue(private_key_params, kSecUseAuthenticationContext);
   CFDictionarySetValue(params_copy, kSecPrivateKeyAttrs, private_key_params);
@@ -92,8 +94,7 @@
       CFDictionaryCreateMutableCopy(kCFAllocatorDefault, /*capacity=*/0,
                                     params));
   CFDictionarySetValue(keychain_item, kSecValueRef, private_key.get());
-  items_.emplace_back(
-      base::ScopedCFTypeRef<CFDictionaryRef>(keychain_item.release()));
+  items_.emplace_back(keychain_item.release());
 
   return private_key;
 }
@@ -114,7 +115,7 @@
 
   // Filter the items based on `query`.
   base::ScopedCFTypeRef<CFMutableArrayRef> items(
-      CFArrayCreateMutable(NULL, items_.size(), &kCFTypeArrayCallBacks));
+      CFArrayCreateMutable(nullptr, items_.size(), &kCFTypeArrayCallBacks));
   for (auto& item : items_) {
     // Each `Keychain` instance is expected to operate only on items of a single
     // keychain-access-group, which is tied to the `Profile`.
@@ -225,6 +226,4 @@
   ClearInstanceOverride();
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/fake_touch_id_context.h b/device/fido/mac/fake_touch_id_context.h
index 2102fb22..80d4d63 100644
--- a/device/fido/mac/fake_touch_id_context.h
+++ b/device/fido/mac/fake_touch_id_context.h
@@ -8,9 +8,7 @@
 #include "base/component_export.h"
 #include "device/fido/mac/touch_id_context.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 class FakeTouchIdContext : public TouchIdContext {
  public:
@@ -38,8 +36,6 @@
   bool resolve_next_prompt_ = true;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_FAKE_TOUCH_ID_CONTEXT_H_
diff --git a/device/fido/mac/fake_touch_id_context.mm b/device/fido/mac/fake_touch_id_context.mm
index f7fe16c..dfabb58e 100644
--- a/device/fido/mac/fake_touch_id_context.mm
+++ b/device/fido/mac/fake_touch_id_context.mm
@@ -7,9 +7,11 @@
 #include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 FakeTouchIdContext::FakeTouchIdContext() = default;
 FakeTouchIdContext::~FakeTouchIdContext() = default;
@@ -27,6 +29,4 @@
   // destroyed, so no members should be used beyond this point.
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/get_assertion_operation.mm b/device/fido/mac/get_assertion_operation.mm
index 99c326d2..0e2f6a9 100644
--- a/device/fido/mac/get_assertion_operation.mm
+++ b/device/fido/mac/get_assertion_operation.mm
@@ -26,6 +26,10 @@
 #include "device/fido/strings/grit/fido_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device::fido::mac {
 
 using base::ScopedCFTypeRef;
diff --git a/device/fido/mac/get_assertion_operation_unittest_mac.mm b/device/fido/mac/get_assertion_operation_unittest_mac.mm
index 91e3fd4..7b7fb959 100644
--- a/device/fido/mac/get_assertion_operation_unittest_mac.mm
+++ b/device/fido/mac/get_assertion_operation_unittest_mac.mm
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <array>
-
 #include <Foundation/Foundation.h>
 #include <Security/Security.h>
 
-#include "base/strings/string_number_conversions.h"
+#include <array>
 
+#include "base/strings/string_number_conversions.h"
 #include "base/test/task_environment.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_test_data.h"
@@ -20,6 +19,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace device::fido::mac {
 
 namespace {
diff --git a/device/fido/mac/keychain.h b/device/fido/mac/keychain.h
index 951a5ece..4e790de 100644
--- a/device/fido/mac/keychain.h
+++ b/device/fido/mac/keychain.h
@@ -13,15 +13,13 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/no_destructor.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 // Keychain wraps some operations from the macOS Security framework to work with
 // keys and keychain items.
 //
 // The Touch ID authenticator creates keychain items in the "iOS-style"
-// keychain, which scopes item access based on the application-identifer or
+// keychain, which scopes item access based on the application-identifier or
 // keychain-access-group entitlements, and therefore requires code signing with
 // a real Apple developer ID. We therefore group these function here, so they
 // can be mocked out in testing.
@@ -68,8 +66,7 @@
   static void SetInstanceOverride(Keychain* keychain);
   static void ClearInstanceOverride();
 };
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_KEYCHAIN_H_
diff --git a/device/fido/mac/keychain.mm b/device/fido/mac/keychain.mm
index 5d1cb805..cc8f94e 100644
--- a/device/fido/mac/keychain.mm
+++ b/device/fido/mac/keychain.mm
@@ -10,9 +10,11 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/no_destructor.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 static Keychain* g_keychain_instance_override = nullptr;
 
@@ -73,6 +75,4 @@
   return SecItemUpdate(query, keychain_data);
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/make_credential_operation.h b/device/fido/mac/make_credential_operation.h
index 74340355..03a995f 100644
--- a/device/fido/mac/make_credential_operation.h
+++ b/device/fido/mac/make_credential_operation.h
@@ -16,9 +16,7 @@
 #include "device/fido/mac/operation.h"
 #include "device/fido/mac/touch_id_context.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 // MakeCredentialOperation implements the authenticatorMakeCredential operation.
 // The operation can be invoked via its |Run| method, which must only be called
@@ -55,8 +53,6 @@
   Callback callback_;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_MAKE_CREDENTIAL_OPERATION_H_
diff --git a/device/fido/mac/make_credential_operation.mm b/device/fido/mac/make_credential_operation.mm
index 9532995c..06fb64e63 100644
--- a/device/fido/mac/make_credential_operation.mm
+++ b/device/fido/mac/make_credential_operation.mm
@@ -30,9 +30,11 @@
 #include "device/fido/strings/grit/fido_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 MakeCredentialOperation::MakeCredentialOperation(
     CtapMakeCredentialRequest request,
@@ -167,6 +169,4 @@
                            std::move(response));
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/make_credential_operation_unittest_mac.mm b/device/fido/mac/make_credential_operation_unittest_mac.mm
index d208450..81cde4e 100644
--- a/device/fido/mac/make_credential_operation_unittest_mac.mm
+++ b/device/fido/mac/make_credential_operation_unittest_mac.mm
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <array>
-
 #include <Foundation/Foundation.h>
 #include <Security/Security.h>
 
-#include "base/strings/string_number_conversions.h"
+#include <array>
 
+#include "base/strings/string_number_conversions.h"
 #include "base/test/task_environment.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_test_data.h"
@@ -19,9 +18,11 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 namespace {
 
 using test::TestCallbackReceiver;
@@ -64,6 +65,4 @@
 }
 
 }  // namespace
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/operation.h b/device/fido/mac/operation.h
index 568c3ff..130df4a 100644
--- a/device/fido/mac/operation.h
+++ b/device/fido/mac/operation.h
@@ -5,9 +5,7 @@
 #ifndef DEVICE_FIDO_MAC_OPERATION_H_
 #define DEVICE_FIDO_MAC_OPERATION_H_
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 class Operation {
  public:
@@ -20,8 +18,6 @@
   virtual void Run() = 0;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_OPERATION_H_
diff --git a/device/fido/mac/scoped_touch_id_test_environment.h b/device/fido/mac/scoped_touch_id_test_environment.h
index c1d01a67..8e56aee 100644
--- a/device/fido/mac/scoped_touch_id_test_environment.h
+++ b/device/fido/mac/scoped_touch_id_test_environment.h
@@ -12,9 +12,7 @@
 #include "base/component_export.h"
 #include "device/fido/mac/authenticator_config.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 class FakeTouchIdContext;
 class ScopedFakeKeychain;
@@ -71,8 +69,6 @@
   bool touch_id_available_ = true;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_SCOPED_TOUCH_ID_TEST_ENVIRONMENT_H_
diff --git a/device/fido/mac/scoped_touch_id_test_environment.mm b/device/fido/mac/scoped_touch_id_test_environment.mm
index 0a47ad3..6ac947d1 100644
--- a/device/fido/mac/scoped_touch_id_test_environment.mm
+++ b/device/fido/mac/scoped_touch_id_test_environment.mm
@@ -14,9 +14,11 @@
 #include "device/fido/mac/fake_keychain.h"
 #include "device/fido/mac/fake_touch_id_context.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 static ScopedTouchIdTestEnvironment* g_current_environment = nullptr;
 
@@ -94,6 +96,4 @@
   return std::move(next_touch_id_context_);
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/touch_id_context.h b/device/fido/mac/touch_id_context.h
index e68b876..33891c6 100644
--- a/device/fido/mac/touch_id_context.h
+++ b/device/fido/mac/touch_id_context.h
@@ -13,13 +13,10 @@
 #include "base/component_export.h"
 #include "base/functional/callback.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/memory/weak_ptr.h"
 #include "device/fido/mac/credential_store.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 struct AuthenticatorConfig;
 
@@ -79,15 +76,13 @@
 
   void RunCallback(bool success);
 
-  base::scoped_nsobject<LAContext> context_;
+  LAContext* __strong context_;
   Callback callback_;
   base::WeakPtrFactory<TouchIdContext> weak_ptr_factory_{this};
 
   friend class ScopedTouchIdTestEnvironment;
 };
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_TOUCH_ID_CONTEXT_H_
diff --git a/device/fido/mac/touch_id_context.mm b/device/fido/mac/touch_id_context.mm
index 77f167d..6655a87 100644
--- a/device/fido/mac/touch_id_context.mm
+++ b/device/fido/mac/touch_id_context.mm
@@ -10,6 +10,7 @@
 
 #include "base/functional/bind.h"
 #include "base/logging.h"
+#include "base/mac/bridging.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/memory/ptr_util.h"
@@ -23,9 +24,11 @@
 #include "device/fido/mac/authenticator_config.h"
 #include "device/fido/mac/keychain.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 namespace {
 
@@ -47,7 +50,7 @@
     return false;
   }
 
-  NSArray* entitlement_value_nsarray = base::mac::CFToNSCast(
+  NSArray* entitlement_value_nsarray = base::mac::CFToNSPtrCast(
       base::mac::CFCast<CFArrayRef>(entitlement_value_cftype));
   if (!entitlement_value_nsarray) {
     return false;
@@ -69,9 +72,10 @@
                                 &kCFTypeDictionaryValueCallBacks));
   CFDictionarySetValue(params, kSecAttrKeyType,
                        kSecAttrKeyTypeECSECPrimeRandom);
-  CFDictionarySetValue(params, kSecAttrKeySizeInBits, @256);
+  CFDictionarySetValue(params, kSecAttrKeySizeInBits,
+                       base::mac::NSToCFPtrCast(@256));
   CFDictionarySetValue(params, kSecAttrTokenID, kSecAttrTokenIDSecureEnclave);
-  CFDictionarySetValue(params, kSecAttrIsPermanent, @NO);
+  CFDictionarySetValue(params, kSecAttrIsPermanent, kCFBooleanFalse);
 
   base::ScopedCFTypeRef<CFErrorRef> cferr;
   base::ScopedCFTypeRef<SecKeyRef> private_key(
@@ -120,7 +124,7 @@
     return false;
   }
 
-  base::scoped_nsobject<LAContext> context([[LAContext alloc] init]);
+  LAContext* context = [[LAContext alloc] init];
   NSError* nserr;
   if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication
                             error:&nserr]) {
@@ -188,12 +192,10 @@
                                 // |error| is autoreleased in this block. It
                                 // is not currently passed onto the other
                                 // thread running the callback; but if it
-                                // were, it would have to be retained first
-                                // (and probably captured in a
-                                // scoped_nsobject<NSError>).
+                                // were, it would have to be retained first.
                                 DCHECK(error != nil);
                                 DVLOG(1) << "Touch ID prompt failed: "
-                                         << base::mac::NSToCFCast(error);
+                                         << base::mac::NSToCFPtrCast(error);
                               }
                               runner->PostTask(
                                   FROM_HERE,
@@ -206,6 +208,4 @@
   std::move(callback_).Run(success);
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/util.h b/device/fido/mac/util.h
index 426978e..bdd1c53 100644
--- a/device/fido/mac/util.h
+++ b/device/fido/mac/util.h
@@ -22,9 +22,7 @@
 #include "device/fido/p256_public_key.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 
 // MakeAttestedCredentialData returns an AttestedCredentialData instance for
 // the Touch ID authenticator credential ID and public key or |absl::nullopt|
@@ -73,8 +71,6 @@
 // closed).
 bool DeviceHasBiometricsAvailable();
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
 
 #endif  // DEVICE_FIDO_MAC_UTIL_H_
diff --git a/device/fido/mac/util.mm b/device/fido/mac/util.mm
index f83cdd7..49f88b6 100644
--- a/device/fido/mac/util.mm
+++ b/device/fido/mac/util.mm
@@ -14,7 +14,6 @@
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_logging.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/cbor/writer.h"
@@ -24,14 +23,15 @@
 #include "device/fido/p256_public_key.h"
 #include "device/fido/public_key.h"
 
-namespace device {
-namespace fido {
-namespace mac {
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace device::fido::mac {
 
 using base::ScopedCFTypeRef;
-using base::scoped_nsobject;
-using cbor::Writer;
 using cbor::Value;
+using cbor::Writer;
 
 // The Touch ID authenticator AAGUID value. Despite using self-attestation,
 // Chrome will return this non-zero AAGUID for all MakeCredential
@@ -167,19 +167,17 @@
   }
 
   base::ScopedCFTypeRef<CFStringRef> sign_id(
-      SecTaskCopySigningIdentifier(task.get(), /* error= */ nullptr));
+      SecTaskCopySigningIdentifier(task.get(), /*error=*/nullptr));
   return static_cast<bool>(sign_id) ? CodeSigningState::kSigned
                                     : CodeSigningState::kNotSigned;
 }
 
 bool DeviceHasBiometricsAvailable() {
-  base::scoped_nsobject<LAContext> context([[LAContext alloc] init]);
+  LAContext* context = [[LAContext alloc] init];
   NSError* nserr;
   return
       [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                            error:&nserr];
 }
 
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/device/fido/mac/util_unittest.cc b/device/fido/mac/util_unittest.cc
index 75a6a9a..1058679c 100644
--- a/device/fido/mac/util_unittest.cc
+++ b/device/fido/mac/util_unittest.cc
@@ -16,9 +16,7 @@
 
 using testing::ElementsAre;
 
-namespace device {
-namespace fido {
-namespace mac {
+namespace device::fido::mac {
 namespace {
 
 static base::Time g_fake_now;
@@ -50,6 +48,4 @@
 }
 
 }  // namespace
-}  // namespace mac
-}  // namespace fido
-}  // namespace device
+}  // namespace device::fido::mac
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index a5391a3a..4624706 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -204,7 +204,6 @@
   sources = [
     "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/content/shell/shell_resources.pak",
     "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak",
     "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak",
@@ -227,7 +226,6 @@
   deps = [
     ":extensions_resources",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/browser/devtools:devtools_resources",
     "//content/shell:resources",
     "//device/bluetooth/strings",
diff --git a/extensions/browser/event_listener_map.cc b/extensions/browser/event_listener_map.cc
index deda70db..95d35821 100644
--- a/extensions/browser/event_listener_map.cc
+++ b/extensions/browser/event_listener_map.cc
@@ -263,6 +263,24 @@
   return false;
 }
 
+bool EventListenerMap::HasProcessListenerForEvent(
+    content::RenderProcessHost* process,
+    int worker_thread_id,
+    const std::string& extension_id,
+    const std::string& event_name) const {
+  for (const auto& it : listeners_) {
+    for (const auto& listener : it.second) {
+      if (listener->process() == process &&
+          listener->extension_id() == extension_id &&
+          listener->worker_thread_id() == worker_thread_id &&
+          listener->event_name() == event_name) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 void EventListenerMap::RemoveListenersForExtension(
     const std::string& extension_id) {
   for (auto it = listeners_.begin(); it != listeners_.end();) {
diff --git a/extensions/browser/event_listener_map.h b/extensions/browser/event_listener_map.h
index 591a61c..af1f608 100644
--- a/extensions/browser/event_listener_map.h
+++ b/extensions/browser/event_listener_map.h
@@ -220,6 +220,11 @@
   bool HasProcessListener(content::RenderProcessHost* process,
                           int worker_thread_id,
                           const std::string& extension_id) const;
+  // As above, but checks for a specific event.
+  bool HasProcessListenerForEvent(content::RenderProcessHost* process,
+                                  int worker_thread_id,
+                                  const std::string& extension_id,
+                                  const std::string& event_name) const;
 
   // Removes any listeners that |extension_id| has added, both lazy and regular.
   void RemoveListenersForExtension(const std::string& extension_id);
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index 279fc6d..af9ef54 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/observer_list.h"
 #include "base/ranges/algorithm.h"
+#include "base/strings/string_util.h"
 #include "components/crx_file/id_util.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -1234,9 +1235,25 @@
   if (!params)
     return;
   DCHECK(event);
-  if (listeners_.HasProcessListener(params->render_process_host,
-                                    params->worker_thread_id,
-                                    params->extension_id)) {
+
+  // TODO(https://crbug.com/1442744): We shouldn't dispatch events to processes
+  // that don't have a listener for that event. Currently, we enforce this for
+  // the webRequest API (since a bug there can result in a request hanging
+  // indefinitely). We don't do this in all cases yet because extensions may be
+  // unknowingly relying on this behavior for listeners registered
+  // asynchronously (which is not supported, but may be happening).
+  bool check_for_specific_event =
+      base::StartsWith(event->event_name, "webRequest");
+  bool dispatch_to_process =
+      check_for_specific_event
+          ? listeners_.HasProcessListenerForEvent(
+                params->render_process_host, params->worker_thread_id,
+                params->extension_id, event->event_name)
+          : listeners_.HasProcessListener(params->render_process_host,
+                                          params->worker_thread_id,
+                                          params->extension_id);
+
+  if (dispatch_to_process) {
     DispatchEventToProcess(
         params->extension_id, params->url, params->render_process_host,
         params->service_worker_version_id, params->worker_thread_id, *event,
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 66e73c5..a4d2796 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -262,7 +262,6 @@
     "//components/guest_view/renderer",
     "//components/version_info",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/public/renderer",
     "//extensions:extensions_resources",
     "//extensions/common",
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn
index a63b281..704cb47 100644
--- a/fuchsia_web/webengine/BUILD.gn
+++ b/fuchsia_web/webengine/BUILD.gn
@@ -129,7 +129,6 @@
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/content/gpu_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
     "$root_gen_dir/net/net_resources.pak",
@@ -141,7 +140,6 @@
   deps = [
     "//components/resources:components_resources",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/browser/resources/gpu:resources",
     "//content/browser/tracing:resources",
     "//gpu/command_buffer/service",
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn
index f52c3b6..1e7a524 100644
--- a/gpu/ipc/service/BUILD.gn
+++ b/gpu/ipc/service/BUILD.gn
@@ -30,8 +30,6 @@
     "gpu_config.h",
     "gpu_init.cc",
     "gpu_init.h",
-    "gpu_memory_ablation_experiment.cc",
-    "gpu_memory_ablation_experiment.h",
     "gpu_memory_buffer_factory.cc",
     "gpu_memory_buffer_factory.h",
     "gpu_watchdog_thread.cc",
@@ -110,11 +108,19 @@
       "built_in_shader_cache_writer.h",
       "gpu_memory_buffer_factory_io_surface.cc",
       "gpu_memory_buffer_factory_io_surface.h",
+      "gpu_vsync_mac.h",
+      "gpu_vsync_mac.mm",
       "image_transport_surface_mac.mm",
       "image_transport_surface_overlay_mac.h",
       "image_transport_surface_overlay_mac.mm",
+      "timer_based_vsync_mac.h",
+      "timer_based_vsync_mac.mm",
     ]
-    deps += [ "//ui/accelerated_widget_mac" ]
+    deps += [
+      "//ui/accelerated_widget_mac",
+      "//ui/display:display",
+      "//ui/display/types:types",
+    ]
     lib_dirs = [ "$mac_sdk_path/usr/lib" ]
     frameworks = [
       "CoreGraphics.framework",
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index 81e4124..25d14df 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -47,7 +47,6 @@
 #include "gpu/ipc/common/memory_stats.h"
 #include "gpu/ipc/service/gpu_channel.h"
 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
-#include "gpu/ipc/service/gpu_memory_ablation_experiment.h"
 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
 #include "third_party/skia/include/core/SkGraphics.h"
@@ -167,10 +166,7 @@
 GpuChannelManager::GpuPeakMemoryMonitor::GpuPeakMemoryMonitor(
     GpuChannelManager* channel_manager,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : ablation_experiment_(
-          std::make_unique<GpuMemoryAblationExperiment>(channel_manager,
-                                                        task_runner)),
-      weak_factory_(this) {}
+    : weak_factory_(this) {}
 
 GpuChannelManager::GpuPeakMemoryMonitor::~GpuPeakMemoryMonitor() = default;
 
@@ -184,12 +180,6 @@
   if (sequence != sequence_trackers_.end()) {
     *out_peak_memory = sequence->second.total_memory_;
     allocation_per_source = sequence->second.peak_memory_per_source_;
-
-    uint64_t ablation_memory =
-        ablation_experiment_->GetPeakMemory(sequence_num);
-    *out_peak_memory += ablation_memory;
-    allocation_per_source[GpuPeakMemoryAllocationSource::SHARED_IMAGE_STUB] +=
-        ablation_memory;
   }
   return allocation_per_source;
 }
@@ -199,7 +189,6 @@
   sequence_trackers_.emplace(
       sequence_num,
       SequenceTracker(current_memory_, current_memory_per_source_));
-  ablation_experiment_->StartSequence(sequence_num);
   TRACE_EVENT_ASYNC_BEGIN2("gpu", "PeakMemoryTracking", sequence_num, "start",
                            current_memory_, "start_sources",
                            StartTrackingTracedValue());
@@ -213,7 +202,6 @@
                            sequence->second.total_memory_, "end_sources",
                            StopTrackingTracedValue(sequence->second));
     sequence_trackers_.erase(sequence);
-    ablation_experiment_->StopSequence(sequence_num);
   }
 }
 
@@ -296,7 +284,6 @@
   current_memory_ += diff;
   current_memory_per_source_[source] += diff;
 
-  ablation_experiment_->OnMemoryAllocated(old_size, new_size);
   if (old_size < new_size) {
     // When memory has increased, iterate over the sequences to update their
     // peak.
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h
index fc3e2f4..e9a6c052 100644
--- a/gpu/ipc/service/gpu_channel_manager.h
+++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -62,7 +62,6 @@
 struct GpuPreferences;
 class GpuChannel;
 class GpuChannelManagerDelegate;
-class GpuMemoryAblationExperiment;
 class GpuMemoryBufferFactory;
 class GpuWatchdogThread;
 class ImageDecodeAcceleratorWorker;
@@ -310,7 +309,6 @@
     base::flat_map<GpuPeakMemoryAllocationSource, uint64_t>
         current_memory_per_source_;
 
-    std::unique_ptr<GpuMemoryAblationExperiment> ablation_experiment_;
     base::WeakPtrFactory<GpuPeakMemoryMonitor> weak_factory_;
   };
 
diff --git a/gpu/ipc/service/gpu_memory_ablation_experiment.cc b/gpu/ipc/service/gpu_memory_ablation_experiment.cc
deleted file mode 100644
index 34eb18bc..0000000
--- a/gpu/ipc/service/gpu_memory_ablation_experiment.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/ipc/service/gpu_memory_ablation_experiment.h"
-
-#include <algorithm>
-
-#include "base/functional/bind.h"
-#include "base/metrics/field_trial_params.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task/sequenced_task_runner.h"
-#include "base/time/time.h"
-#include "base/trace_event/common/trace_event_common.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/shared_image_usage.h"
-#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
-#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
-#include "gpu/ipc/common/surface_handle.h"
-#include "gpu/ipc/service/gpu_channel_manager.h"
-#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/gpu/GrDirectContext.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface.h"
-
-namespace gpu {
-
-// Main feature flag to control the entire experiment, encompassing bot CPU and
-// GPU ablations.
-BASE_FEATURE(kGPUMemoryAblationFeature,
-             "GPUMemoryAblation",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-// Field Trial Parameter that defines the size of memory allocations.
-const char kGPUMemoryAblationFeatureSizeParam[] = "Size";
-
-// Image allocation parameters.
-constexpr viz::SharedImageFormat kFormat = viz::SinglePlaneFormat::kRGBA_8888;
-constexpr uint32_t kUsage = SHARED_IMAGE_USAGE_DISPLAY_READ;
-
-bool GpuMemoryAblationExperiment::ExperimentSupported() {
-  if (!base::FeatureList::IsEnabled(kGPUMemoryAblationFeature))
-    return false;
-  gl::GLImplementation gl_impl = gl::GetGLImplementation();
-  // Mock and Stub implementations are used in tests. It is not possible to
-  // create a valid GrContext with these. A disabled implementation is used by
-  // the GPU Info Collection Process. This also has no graphical output
-  // possible.
-  if (gl_impl == gl::kGLImplementationNone ||
-      gl_impl == gl::kGLImplementationMockGL ||
-      gl_impl == gl::kGLImplementationStubGL ||
-      gl_impl == gl::kGLImplementationDisabled) {
-    return false;
-  }
-  return true;
-}
-
-GpuMemoryAblationExperiment::GpuMemoryAblationExperiment(
-    GpuChannelManager* channel_manager,
-    scoped_refptr<base::SequencedTaskRunner> task_runner)
-    : channel_manager_(channel_manager), task_runner_(task_runner) {
-  if (!GpuMemoryAblationExperiment::ExperimentSupported())
-    init_status_ = Status::DISABLED;
-}
-
-GpuMemoryAblationExperiment::~GpuMemoryAblationExperiment() {
-  // Some unittests don't properly clean up. Clean up our allocations if
-  // necessary.
-  if (mailboxes_.empty())
-    return;
-  bool have_context = context_state_->MakeCurrent(context_state_->surface());
-  factory_->DestroyAllSharedImages(have_context);
-}
-
-void GpuMemoryAblationExperiment::OnMemoryAllocated(uint64_t old_size,
-                                                    uint64_t new_size) {
-  if (init_status_ == Status::DISABLED) {
-    return;
-  } else if (init_status_ == Status::UNINITIALIZED) {
-    if (InitGpu(channel_manager_)) {
-      init_status_ = Status::ENABLED;
-    } else {
-      init_status_ = Status::DISABLED;
-      context_state_ = nullptr;
-      return;
-    }
-  }
-  // TODO(jonross): Investigate why there are 0 size allocations.
-  if (new_size > old_size) {
-    // TODO(jonross): Impl CPU ablation
-    AllocateGpuMemory();
-  } else if (old_size > new_size) {
-    // TODO(jonross): Impl CPU ablation
-    if (!mailboxes_.empty()) {
-      // We need to perform this as a PostTask. Though the delete calls are
-      // similarly nested to the allocations, attempting to restore the
-      // previous context will attempt to restore bindings or surfaces which
-      // were in the process of being deleted. (https://crbug.com/1106926)
-      task_runner_->PostTask(
-          FROM_HERE,
-          base::BindOnce(&GpuMemoryAblationExperiment::DeleteGpuMemory,
-                         weak_factory_.GetWeakPtr()));
-    }
-  }
-}
-
-uint64_t GpuMemoryAblationExperiment::GetPeakMemory(
-    uint32_t sequence_num) const {
-  auto it = sequences_.find(sequence_num);
-  if (it == sequences_.end())
-    return 0u;
-  return it->second;
-}
-
-void GpuMemoryAblationExperiment::StartSequence(uint32_t sequence_num) {
-  sequences_.emplace(sequence_num, 0u);
-}
-
-void GpuMemoryAblationExperiment::StopSequence(uint32_t sequence_num) {
-  auto it = sequences_.find(sequence_num);
-  if (it == sequences_.end())
-    return;
-
-  sequences_.erase(it);
-}
-
-void GpuMemoryAblationExperiment::AllocateGpuMemory() {
-  // We can't successfully create an image without a context, so do not even
-  // perform the initial allocations.
-  std::unique_ptr<ui::ScopedMakeCurrent> scoped_current =
-      ScopedMakeContextCurrent();
-  if (!scoped_current)
-    return;
-
-  auto mailbox = Mailbox::GenerateForSharedImage();
-  auto color_space = gfx::ColorSpace::CreateSRGB();
-
-  if (!factory_->CreateSharedImage(mailbox, kFormat, size_, color_space,
-                                   kTopLeft_GrSurfaceOrigin,
-                                   kPremul_SkAlphaType, gpu::kNullSurfaceHandle,
-                                   kUsage, "GpuMemoryAblation")) {
-    return;
-  }
-
-  auto skia_rep = rep_factory_->ProduceSkia(mailbox, context_state_);
-  if (!skia_rep)
-    return;
-
-  auto write_access = skia_rep->BeginScopedWriteAccess(
-      /*begin_semaphores=*/{}, /*end_semaphores=*/{},
-      SharedImageRepresentation::AllowUnclearedAccess::kYes);
-  if (!write_access)
-    return;
-
-  auto* canvas = write_access->surface()->getCanvas();
-  canvas->clear(SkColors::kWhite);
-
-  mailboxes_.push_back(mailbox);
-}
-
-void GpuMemoryAblationExperiment::DeleteGpuMemory() {
-  if (mailboxes_.empty())
-    return;
-
-  auto mailbox = mailboxes_.front();
-  // We can't successfully destroy the image if we cannot get the context,
-  // however we still need to cleanup our internal state.
-  //
-  // Unlike in initialization and allocating memory, we cannot use an
-  // ui::ScopedMakeCurrent here. Though we use a PostTask to separate the
-  // delete calls from the nesting, attempting to restore the previous context
-  // will attempt to restore bindings or surfaces which were in the process of
-  // being deleted. (https://crbug.com/1106926)
-  if (context_state_->MakeCurrent(nullptr))
-    factory_->DestroySharedImage(mailbox);
-
-  mailboxes_.erase(mailboxes_.begin());
-}
-
-bool GpuMemoryAblationExperiment::InitGpu(GpuChannelManager* channel_manager) {
-  ContextResult result;
-  context_state_ = channel_manager->GetSharedContextState(&result);
-  if (result != ContextResult::kSuccess)
-    return false;
-
-  const int default_value = 0;
-  int arg_value = base::GetFieldTrialParamByFeatureAsInt(
-      kGPUMemoryAblationFeature, kGPUMemoryAblationFeatureSizeParam,
-      default_value);
-  if (arg_value == default_value)
-    return false;
-  int texture_size =
-      std::min(256 * arg_value, context_state_->gr_context()->maxTextureSize());
-  size_ = gfx::Size(texture_size, texture_size);
-
-  std::unique_ptr<ui::ScopedMakeCurrent> scoped_current =
-      ScopedMakeContextCurrent();
-  if (!scoped_current)
-    return false;
-
-  factory_ = std::make_unique<SharedImageFactory>(
-      channel_manager->gpu_preferences(),
-      channel_manager->gpu_driver_bug_workarounds(),
-      channel_manager->gpu_feature_info(), context_state_.get(),
-      channel_manager->shared_image_manager(), this,
-      /*is_for_display_compositor=*/false);
-
-  rep_factory_ = std::make_unique<SharedImageRepresentationFactory>(
-      channel_manager->shared_image_manager(), this);
-  return true;
-}
-
-std::unique_ptr<ui::ScopedMakeCurrent>
-GpuMemoryAblationExperiment::ScopedMakeContextCurrent() {
-  std::unique_ptr<ui::ScopedMakeCurrent> scoped_current =
-      std::make_unique<ui::ScopedMakeCurrent>(context_state_->context(),
-                                              context_state_->surface());
-  if (!context_state_->IsCurrent(context_state_->surface()))
-    return nullptr;
-  return scoped_current;
-}
-
-// MemoryTracker:
-void GpuMemoryAblationExperiment::TrackMemoryAllocatedChange(int64_t delta) {
-  DCHECK(delta >= 0 || gpu_allocation_size_ >= static_cast<uint64_t>(-delta));
-  gpu_allocation_size_ += delta;
-  for (auto& it : sequences_) {
-    if (gpu_allocation_size_ > it.second)
-      it.second = gpu_allocation_size_;
-  }
-}
-
-// Unused methods that form the basis of memory dumps
-uint64_t GpuMemoryAblationExperiment::GetSize() const {
-  return 0u;
-}
-
-uint64_t GpuMemoryAblationExperiment::ClientTracingId() const {
-  return 0u;
-}
-
-int GpuMemoryAblationExperiment::ClientId() const {
-  return 0;
-}
-
-uint64_t GpuMemoryAblationExperiment::ContextGroupTracingId() const {
-  return 0u;
-}
-
-}  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_ablation_experiment.h b/gpu/ipc/service/gpu_memory_ablation_experiment.h
deleted file mode 100644
index 748ae66e..0000000
--- a/gpu/ipc/service/gpu_memory_ablation_experiment.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_IPC_SERVICE_GPU_MEMORY_ABLATION_EXPERIMENT_H_
-#define GPU_IPC_SERVICE_GPU_MEMORY_ABLATION_EXPERIMENT_H_
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/containers/flat_map.h"
-#include "base/feature_list.h"
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/memory/weak_ptr.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/ipc/service/gpu_ipc_service_export.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/scoped_make_current.h"
-
-namespace base {
-class SequencedTaskRunner;
-}
-
-namespace gpu {
-class GpuChannelManager;
-class SharedContextState;
-class SharedImageFactory;
-class SharedImageRepresentationFactory;
-
-BASE_DECLARE_FEATURE(kGPUMemoryAblationFeature);
-
-// When enabled, this experiment allocates additional memory alongside each
-// normal allocation. This will allow a study of the correlation between
-// memory usage and performance metrics.
-//
-// Each increase reported to OnMemoryAllocated will allocate a chunk of memory.
-// Each decrease reported will release a previously allocated chunk.
-//
-// GpuMemoryAblationExperiment acts as the MemoryTracker for all of its own
-// allocations. This prevents a cycle of memory allocations:
-//    - GpuChannelManager::GpuPeakMemoryMonitor::OnMemoryAllocatedChange
-//    - GpuMemoryAblationExperiment::OnMemoryAllocated
-//    - MemoryTracker::TrackMemoryAllocatedChange
-//    - GpuChannelManager::GpuPeakMemoryMonitor::OnMemoryAllocatedChange
-//    - etc.
-//
-// Instead this will track the memory it allocated, which can be retrieved via
-// GetPeakMemory.
-class GPU_IPC_SERVICE_EXPORT GpuMemoryAblationExperiment
-    : public MemoryTracker {
- public:
-  // Checks that the memory ablation experiment feature is enabled. As well as
-  // that a supported gl::GLImplementation is available.
-  static bool ExperimentSupported();
-
-  GpuMemoryAblationExperiment(
-      GpuChannelManager* channel_manager,
-      scoped_refptr<base::SequencedTaskRunner> task_runner);
-  ~GpuMemoryAblationExperiment() override;
-
-  // Allocates a chunk of memory in response to increases. Reported decreases
-  // will release previously allocated chunks. The amount of memory allocated
-  // is returned in bytes.
-  void OnMemoryAllocated(uint64_t old_size, uint64_t new_size);
-
-  uint64_t GetPeakMemory(uint32_t sequence_num) const;
-  void StartSequence(uint32_t sequence_num);
-  void StopSequence(uint32_t sequence_num);
-
- private:
-  // The initialization status of the feature. It defaults to |UNINITIALIZED|
-  // and is updated upon the success or failure of initializing the needed GPU
-  // resources.
-  enum class Status {
-    UNINITIALIZED,
-    ENABLED,
-    DISABLED,
-  };
-
-  void AllocateGpuMemory();
-  void DeleteGpuMemory();
-
-  // Setups the Gpu resources needed to allocate Gpu RAM. These are influenced
-  // by SharedImageStub. Which is not used directly as there is no external
-  // host to pair a GpuChannel with. Returns true if initialization succeeded.
-  bool InitGpu(GpuChannelManager* channel_manager);
-
-  // This must be called before any actions on |factory_|.
-  // This provides a ui::ScopedMakeCurrent which will reset the previous
-  // context upon deletion. As the we allocate memory in-response to other
-  // allocations, we are changing the context in a nested fashion. Several
-  // areas of code do not support this, and re-verify the current context at
-  // later points. (https://crbug.com/1104316)
-  // If this method fails then a nullptr is returned. All subsequent work on
-  // the |factory_| would also fail.
-  std::unique_ptr<ui::ScopedMakeCurrent> ScopedMakeContextCurrent();
-
-  // MemoryTracker:
-  void TrackMemoryAllocatedChange(int64_t delta) override;
-  uint64_t GetSize() const override;
-  uint64_t ClientTracingId() const override;
-  int ClientId() const override;
-  uint64_t ContextGroupTracingId() const override;
-
-  // The status of the initialization. Will be updated based on the results of
-  // initializing the necessary GPU resources.
-  Status init_status_ = Status::UNINITIALIZED;
-
-  // Size of image to allocate, determined by experiment parameters.
-  gfx::Size size_;
-
-  // The Mailboxes allocated for each image.
-  std::vector<Mailbox> mailboxes_;
-
-  // The memory allocated for ablation is not reported directly to
-  // GpuChannelManager::GpuPeakMemoryMonitor, as GpuMemoryAblationExperiment
-  // acts as the MemoryTracker for its own allocations. This tracks the peak
-  // allocation so that it can be reported.
-  base::flat_map<uint32_t /*sequence_num*/, uint64_t /*peak_memory*/>
-      sequences_;
-
-  // The memory allocated for ablation is not reported directly to
-  // GpuChannelManager::GpuPeakMemoryMonitor, as this class acts as the
-  // MemoryTracker for its own allocations. Tracks the current amount of
-  //  memory allocated as a part of the ablation.
-  uint64_t gpu_allocation_size_ = 0;
-
-  scoped_refptr<SharedContextState> context_state_;
-  std::unique_ptr<SharedImageFactory> factory_;
-  std::unique_ptr<SharedImageRepresentationFactory> rep_factory_;
-  raw_ptr<GpuChannelManager> channel_manager_;
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  base::WeakPtrFactory<GpuMemoryAblationExperiment> weak_factory_{this};
-};
-
-}  // namespace gpu
-
-#endif  // GPU_IPC_SERVICE_GPU_MEMORY_ABLATION_EXPERIMENT_H_
diff --git a/gpu/ipc/service/gpu_vsync_mac.h b/gpu/ipc/service/gpu_vsync_mac.h
new file mode 100644
index 0000000..c0c1b0e
--- /dev/null
+++ b/gpu/ipc/service/gpu_vsync_mac.h
@@ -0,0 +1,60 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_IPC_SERVICE_GPU_VSYNC_MAC_H_
+#define GPU_IPC_SERVICE_GPU_VSYNC_MAC_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/time/time.h"
+#include "components/viz/common/gpu/gpu_vsync_callback.h"
+#include "gpu/ipc/service/timer_based_vsync_mac.h"
+#include "ui/display/mac/display_link_mac.h"
+#include "ui/display/types/display_constants.h"
+
+namespace gpu {
+
+// Each ImageTransportSurfaceOverlayMacEGL creates a GpuVSyncMac,
+class GpuVSyncMac {
+ public:
+  explicit GpuVSyncMac(viz::GpuVSyncCallback vsync_callback);
+  ~GpuVSyncMac();
+
+  void SetVSyncDisplayID(int64_t display_id);
+  void SetGpuVSyncEnabled(bool enabled);
+
+ private:
+  // Register a DisplayLinkMac callback. If it fails, the timer will be used
+  // instead.
+  void OnDisplayLinkCallback(ui::VSyncParamsMac params);
+
+  void AddGpuVSyncCallback();
+  void RemoveGpuVSyncCallback();
+
+  // This is the Viz callback for BeginFrame.
+  const viz::GpuVSyncCallback vsync_callback_;
+
+  // The timer works as GpuVsync when CVDisplayLink fails.
+  raw_ptr<TimerBasedVsyncMac> timer_based_vsync_mac_;
+
+  // CGDirectDisplayID of the current monitor used for Creating CVDisplayLink.
+  int64_t display_id_ = display::kInvalidDisplayId;
+
+  // The default frame rate is 60 Hz (16 ms).
+  base::TimeDelta nominal_refresh_period_ = base::Hertz(60);
+
+  // Start GpuVsync. Vis enables it when BeginFrame is needed.
+  bool gpu_vsync_enabled_ = false;
+
+  scoped_refptr<ui::DisplayLinkMac> display_link_mac_;
+
+  // CVDisplayLink callback. |vsync_callback_mac_| calls the viz callback runner
+  // that will runs on the viz thread.
+  std::unique_ptr<ui::VSyncCallbackMac> vsync_callback_mac_;
+
+  base::WeakPtrFactory<GpuVSyncMac> weak_ptr_factory_{this};
+};
+}  // namespace gpu
+
+#endif  // GPU_IPC_SERVICE_GPU_VSYNC_MAC_H_
diff --git a/gpu/ipc/service/gpu_vsync_mac.mm b/gpu/ipc/service/gpu_vsync_mac.mm
new file mode 100644
index 0000000..299db1dd
--- /dev/null
+++ b/gpu/ipc/service/gpu_vsync_mac.mm
@@ -0,0 +1,147 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/ipc/service/gpu_vsync_mac.h"
+
+#include "base/feature_list.h"
+#include "base/functional/bind.h"
+#include "base/logging.h"
+
+namespace gpu {
+namespace {
+BASE_FEATURE(kForceGpuVSyncTimerForDebugging,
+             "ForceGpuVSyncTimerForDebugging",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+}  // namespace
+
+GpuVSyncMac::GpuVSyncMac(viz::GpuVSyncCallback vsync_callback)
+    : vsync_callback_(vsync_callback) {}
+
+GpuVSyncMac::~GpuVSyncMac() {
+  if (display_link_mac_) {
+    vsync_callback_mac_ = nullptr;
+    display_link_mac_ = nullptr;
+  } else {
+    timer_based_vsync_mac_->RemoveVSyncTimerCallback(vsync_callback_);
+  }
+}
+
+void GpuVSyncMac::SetVSyncDisplayID(int64_t display_id) {
+  if (display_id == display::kInvalidDisplayId) {
+    timer_based_vsync_mac_ = TimerBasedVsyncMac::GetInstance();
+    DLOG(ERROR) << "GpuVSyncMac: DisplayLink Display ID is not available. "
+                   "Switch to timer for GpuVSync.";
+  }
+
+  if (display_id_ == display_id) {
+    return;
+  }
+
+  // Remove callback from Timer if Timer is used.
+  if (!display_link_mac_ && gpu_vsync_enabled_) {
+    timer_based_vsync_mac_->RemoveVSyncTimerCallback(vsync_callback_);
+  }
+
+  // Remove and unregister the old VSyncCallbackMac.
+  vsync_callback_mac_ = nullptr;
+
+  // Remove the old DisplayLinkMac.
+  display_link_mac_ = nullptr;
+  display_id_ = display_id;
+
+  // Get DisplayLinkMac with the new CGDirectDisplayID.
+  display_link_mac_ = ui::DisplayLinkMac::GetForDisplay(
+      base::checked_cast<CGDirectDisplayID>(display_id));
+
+  // For debugging only.
+  static const bool force_timer =
+      base::FeatureList::IsEnabled(kForceGpuVSyncTimerForDebugging);
+  if (force_timer) {
+    display_link_mac_ = nullptr;
+  }
+
+  if (display_link_mac_) {
+    nominal_refresh_period_ =
+        base::Seconds(1) / display_link_mac_->GetRefreshRate();
+  } else {
+    LOG(ERROR) << "Fail to create DisplayLinkMac for DisplayID: " << display_id
+               << ". Use timer for GpuVSync";
+    timer_based_vsync_mac_ = TimerBasedVsyncMac::GetInstance();
+  }
+
+  if (gpu_vsync_enabled_) {
+    AddGpuVSyncCallback();
+  }
+}
+
+void GpuVSyncMac::SetGpuVSyncEnabled(bool enabled) {
+  if (gpu_vsync_enabled_ == enabled) {
+    return;
+  }
+  gpu_vsync_enabled_ = enabled;
+
+  if (enabled) {
+    AddGpuVSyncCallback();
+  } else {
+    RemoveGpuVSyncCallback();
+  }
+}
+
+void GpuVSyncMac::AddGpuVSyncCallback() {
+  if (display_link_mac_) {
+    DCHECK(!vsync_callback_mac_);
+    // Request the callback to be called on the hihg-priority system
+    // VCDisplayLink thread.
+    vsync_callback_mac_ = display_link_mac_->RegisterCallback(
+        base::BindRepeating(&GpuVSyncMac::OnDisplayLinkCallback,
+                            weak_ptr_factory_.GetWeakPtr()),
+        /*do_callback_on_register_thread=*/false);
+    if (vsync_callback_mac_) {
+      // RegisterCallback succeeded.
+      return;
+    } else {
+      // Failed. Destroy DisplaylinkMac and switch to timer.
+      display_link_mac_ = nullptr;
+      LOG(ERROR) << "Fail to start CVDisplayLink callback for DisplayID: "
+                 << display_id_ << ". Switch to timer for GpuVSync";
+
+      timer_based_vsync_mac_ = TimerBasedVsyncMac::GetInstance();
+    }
+  }
+
+  // Use timer.
+  timer_based_vsync_mac_->AddVSyncTimerCallback(vsync_callback_);
+}
+
+void GpuVSyncMac::RemoveGpuVSyncCallback() {
+  if (display_link_mac_) {
+    DCHECK(vsync_callback_mac_);
+    // Remove and unregister VSyncCallbackMac.
+    vsync_callback_mac_ = nullptr;
+    return;
+  }
+  // The timer is in use.
+  timer_based_vsync_mac_->RemoveVSyncTimerCallback(vsync_callback_);
+}
+
+// Called on a high priority CVDisplayLink thread.
+void GpuVSyncMac::OnDisplayLinkCallback(ui::VSyncParamsMac params) {
+  base::TimeTicks timebase;
+  base::TimeDelta interval;
+
+  if (params.callback_times_valid) {
+    DCHECK(params.callback_timebase != base::TimeTicks());
+    DCHECK(!params.callback_interval.is_zero());
+    timebase = params.callback_timebase;
+    interval = params.callback_interval;
+  } else {
+    // Invalid parameters should be rare. Use default refresh rate.
+    timebase = base::TimeTicks::Now();
+    interval = params.display_times_valid ? params.display_interval
+                                          : nominal_refresh_period_;
+  }
+  vsync_callback_.Run(timebase, interval);
+}
+
+}  // namespace gpu
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.h b/gpu/ipc/service/image_transport_surface_overlay_mac.h
index 7d0b810..6c0ab25 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.h
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.h
@@ -9,6 +9,7 @@
 
 #import "base/mac/scoped_nsobject.h"
 #include "base/memory/weak_ptr.h"
+#include "components/viz/common/gpu/gpu_vsync_callback.h"
 #include "gpu/ipc/service/command_buffer_stub.h"
 #include "gpu/ipc/service/image_transport_surface.h"
 #include "ui/gfx/ca_layer_result.h"
@@ -17,6 +18,13 @@
 #include "ui/gl/gl_surface.h"
 #include "ui/gl/presenter.h"
 
+// Put gpu_vsync_mac.h (which includes ui/display/mac/display_link_mac.h)
+// after ui/gl/gl_xxx.h. There is a conflict between MacOSX sdk gltypes.h and
+// third_party/mesa_headers/GL/glext.h
+#if BUILDFLAG(IS_MAC)
+#include "gpu/ipc/service/gpu_vsync_mac.h"
+#endif
+
 @class CAContext;
 @class CALayer;
 
@@ -33,9 +41,6 @@
 
 class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter {
  public:
-  using VSyncCallback =
-      base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>;
-
   ImageTransportSurfaceOverlayMacEGL(
       base::WeakPtr<ImageTransportSurfaceDelegate> delegate);
 
@@ -57,9 +62,11 @@
   void SetCALayerErrorCode(gfx::CALayerResult ca_layer_error_code) override;
 
   // GLSurface override
+#if BUILDFLAG(IS_MAC)
   bool SupportsGpuVSync() const override;
-  void SetGpuVSyncEnabled(bool enabled) override;
   void SetVSyncDisplayID(int64_t display_id) override;
+  void SetGpuVSyncEnabled(bool enabled) override;
+#endif
 
  private:
   ~ImageTransportSurfaceOverlayMacEGL() override;
@@ -85,8 +92,9 @@
   // backpressure.
   uint64_t previous_frame_fence_ = 0;
 
-  const VSyncCallback vsync_callback_;
-  bool gpu_vsync_enabled_ = false;
+#if BUILDFLAG(IS_MAC)
+  std::unique_ptr<GpuVSyncMac> gpu_vsync_mac_;
+#endif
 
   base::WeakPtrFactory<ImageTransportSurfaceOverlayMacEGL> weak_ptr_factory_;
 };
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
index ad8295c..7ecc5ff3 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -57,7 +57,6 @@
     : delegate_(delegate),
       use_remote_layer_api_(ui::RemoteLayerAPISupported()),
       scale_factor_(1),
-      vsync_callback_(delegate->GetGpuVSyncCallback()),
       weak_ptr_factory_(this) {
   static bool av_disabled_at_command_line =
       !base::FeatureList::IsEnabled(kAVFoundationOverlays);
@@ -88,6 +87,13 @@
 #endif
     [ca_context_ setLayer:ca_layer_tree_coordinator_->GetCALayerForDisplay()];
   }
+
+#if BUILDFLAG(IS_MAC)
+  if (features::UseGpuVsync()) {
+    gpu_vsync_mac_ =
+        std::make_unique<GpuVSyncMac>(delegate->GetGpuVSyncCallback());
+  }
+#endif
 }
 
 ImageTransportSurfaceOverlayMacEGL::~ImageTransportSurfaceOverlayMacEGL() {
@@ -259,19 +265,26 @@
   ca_layer_error_code_ = ca_layer_error_code;
 }
 
-void ImageTransportSurfaceOverlayMacEGL::SetVSyncDisplayID(int64_t display_id) {
-}
-
+#if BUILDFLAG(IS_MAC)
 bool ImageTransportSurfaceOverlayMacEGL::SupportsGpuVSync() const {
   return features::UseGpuVsync();
 }
 
-void ImageTransportSurfaceOverlayMacEGL::SetGpuVSyncEnabled(bool enabled) {
-  if (gpu_vsync_enabled_ == enabled) {
+void ImageTransportSurfaceOverlayMacEGL::SetVSyncDisplayID(int64_t display_id) {
+  if (!features::UseGpuVsync()) {
     return;
   }
 
-  gpu_vsync_enabled_ = enabled;
+  gpu_vsync_mac_->SetVSyncDisplayID(display_id);
 }
 
+void ImageTransportSurfaceOverlayMacEGL::SetGpuVSyncEnabled(bool enabled) {
+  if (!features::UseGpuVsync()) {
+    return;
+  }
+
+  gpu_vsync_mac_->SetGpuVSyncEnabled(enabled);
+}
+#endif
+
 }  // namespace gpu
diff --git a/gpu/ipc/service/timer_based_vsync_mac.h b/gpu/ipc/service/timer_based_vsync_mac.h
new file mode 100644
index 0000000..0359d263
--- /dev/null
+++ b/gpu/ipc/service/timer_based_vsync_mac.h
@@ -0,0 +1,74 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_IPC_SERVICE_TIMER_BASED_VSYNC_MAC_H_
+#define GPU_IPC_SERVICE_TIMER_BASED_VSYNC_MAC_H_
+
+#include <vector>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/power_monitor/power_observer.h"
+#include "base/task/single_thread_task_runner.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "components/viz/common/gpu/gpu_vsync_callback.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}  // namespace base
+
+namespace gpu {
+// Created on the GPU main thread. There is only one instance in the GPU
+// process.
+class TimerBasedVsyncMac : public base::PowerSuspendObserver {
+ public:
+  static TimerBasedVsyncMac* GetInstance();
+
+  TimerBasedVsyncMac(const TimerBasedVsyncMac&) = delete;
+  TimerBasedVsyncMac& operator=(const TimerBasedVsyncMac&) = delete;
+
+  // Implementation of base::PowerSuspendObserver
+  void OnSuspend() override;
+  void OnResume() override;
+
+  // The first and the last function after GpuVSyncThread starts running.
+  void Init();
+  void CleanUp();
+
+  void AddVSyncTimerCallback(viz::GpuVSyncCallback callback);
+  void RemoveVSyncTimerCallback(viz::GpuVSyncCallback callback);
+
+ private:
+  friend struct base::DefaultSingletonTraits<TimerBasedVsyncMac>;
+
+  TimerBasedVsyncMac();
+  ~TimerBasedVsyncMac() override;
+
+  // The timer tick for vsync callback.
+  void OnTimerTick();
+
+  // True when it is in a power suspension mode.
+  bool is_suspended_ = false;
+
+  // For delay based timer when VCDisplayLink fails..
+  base::RepeatingClosure tick_closure_;
+
+  base::DeadlineTimer timer_;
+
+  // All GpuVSyncMac call
+  std::vector<viz::GpuVSyncCallback> timer_callbacks_;
+
+  // The default frame rate is 60 Hz (16 ms).
+  const base::TimeDelta nominal_refresh_period_ = base::Hertz(60);
+
+  base::TimeTicks last_target_;
+
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  SEQUENCE_CHECKER(vsync_thread_sequence_checker_);
+};
+
+}  // namespace gpu
+
+#endif  // GPU_IPC_SERVICE_TIMER_BASED_VSYNC_MAC_H_
diff --git a/gpu/ipc/service/timer_based_vsync_mac.mm b/gpu/ipc/service/timer_based_vsync_mac.mm
new file mode 100644
index 0000000..3fced45
--- /dev/null
+++ b/gpu/ipc/service/timer_based_vsync_mac.mm
@@ -0,0 +1,104 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/ipc/service/timer_based_vsync_mac.h"
+
+#include "base/functional/bind.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/power_monitor/power_monitor.h"
+#include "base/task/single_thread_task_runner.h"
+
+#include "base/threading/platform_thread.h"
+
+namespace gpu {
+
+// static
+TimerBasedVsyncMac* TimerBasedVsyncMac::GetInstance() {
+  return base::Singleton<TimerBasedVsyncMac>::get();
+}
+
+TimerBasedVsyncMac::TimerBasedVsyncMac() {
+  // Use delay based timer for GpuVSync when it fails to create DisplayLinkMac.
+  tick_closure_ = base::BindRepeating(&TimerBasedVsyncMac::OnTimerTick,
+                                      base::Unretained(this));
+
+  timer_.SetTaskRunner(base::SingleThreadTaskRunner::GetCurrentDefault());
+
+  DCHECK(base::PowerMonitor::IsInitialized());
+  is_suspended_ =
+      base::PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(this);
+}
+
+TimerBasedVsyncMac::~TimerBasedVsyncMac() {
+  if (timer_.IsRunning()) {
+    timer_.Stop();
+  }
+  timer_callbacks_.clear();
+
+  base::PowerMonitor::RemovePowerSuspendObserver(this);
+}
+
+void TimerBasedVsyncMac::AddVSyncTimerCallback(viz::GpuVSyncCallback callback) {
+  timer_callbacks_.push_back(callback);
+
+  if (!is_suspended_ && !timer_.IsRunning()) {
+    last_target_ = base::TimeTicks::Now() + nominal_refresh_period_;
+    timer_.Start(FROM_HERE, last_target_, tick_closure_,
+                 base::subtle::DelayPolicy::kPrecise);
+  }
+}
+
+void TimerBasedVsyncMac::RemoveVSyncTimerCallback(
+    viz::GpuVSyncCallback callback) {
+  auto timer_it = base::ranges::find(timer_callbacks_, callback);
+  if (timer_it != timer_callbacks_.end()) {
+    timer_callbacks_.erase(timer_it);
+  }
+
+  if (timer_callbacks_.empty() && timer_.IsRunning()) {
+    timer_.Stop();
+  }
+}
+
+// Timer will not stop automatically in power suspension.
+void TimerBasedVsyncMac::OnSuspend() {
+  if (is_suspended_) {
+    return;
+  }
+  is_suspended_ = true;
+
+  if (timer_.IsRunning()) {
+    DCHECK(!timer_callbacks_.empty());
+    timer_.Stop();
+  }
+}
+
+void TimerBasedVsyncMac::OnResume() {
+  if (!is_suspended_) {
+    return;
+  }
+  is_suspended_ = false;
+
+  if (!timer_callbacks_.empty()) {
+    last_target_ = base::TimeTicks::Now() + nominal_refresh_period_;
+    timer_.Start(FROM_HERE, last_target_, tick_closure_,
+                 base::subtle::DelayPolicy::kPrecise);
+  }
+}
+
+void TimerBasedVsyncMac::OnTimerTick() {
+  base::TimeTicks now = base::TimeTicks::Now();
+  for (auto& callback : timer_callbacks_) {
+    callback.Run(now, nominal_refresh_period_);
+  }
+
+  base::TimeTicks next_target = now + nominal_refresh_period_;
+
+  timer_.Start(FROM_HERE, next_target, tick_closure_,
+               base::subtle::DelayPolicy::kPrecise);
+  last_target_ = next_target;
+}
+
+}  // namespace gpu
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index c688b801..c32bc0717 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -65,7 +65,6 @@
   sources = [
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/net/net_resources.pak",
     "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
     "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
@@ -76,7 +75,6 @@
   deps = [
     "//components/resources:components_resources",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//net:net_resources",
     "//third_party/blink/public:resources",
     "//third_party/blink/public:scaled_resources_100_percent",
diff --git a/infra/config/generated/builders/ci/linux-cr23-rel/properties.json b/infra/config/generated/builders/ci/linux-cr23-rel/properties.json
new file mode 100644
index 0000000..698a17f
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-cr23-rel/properties.json
@@ -0,0 +1,60 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-fyi-archive",
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-cr23-rel",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "linux-cr23-rel",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.fyi",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/mac-cr23-rel/properties.json b/infra/config/generated/builders/ci/mac-cr23-rel/properties.json
new file mode 100644
index 0000000..03c9aa5
--- /dev/null
+++ b/infra/config/generated/builders/ci/mac-cr23-rel/properties.json
@@ -0,0 +1,61 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "mac-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "mac-cr23-rel",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "mac-cr23-rel",
+          "group": "tryserver.chromium.mac"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.fyi",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/win-cr23-rel/properties.json b/infra/config/generated/builders/ci/win-cr23-rel/properties.json
new file mode 100644
index 0000000..f14194e1
--- /dev/null
+++ b/infra/config/generated/builders/ci/win-cr23-rel/properties.json
@@ -0,0 +1,59 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "win-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "win-cr23-rel",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "win-cr23-rel",
+          "group": "tryserver.chromium.win"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.fyi",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-cr23-rel/properties.json b/infra/config/generated/builders/try/linux-cr23-rel/properties.json
new file mode 100644
index 0000000..0c32964
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-cr23-rel/properties.json
@@ -0,0 +1,53 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-fyi-archive",
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-cr23-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.linux",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac-cr23-rel/properties.json b/infra/config/generated/builders/try/mac-cr23-rel/properties.json
new file mode 100644
index 0000000..3eadd94c
--- /dev/null
+++ b/infra/config/generated/builders/try/mac-cr23-rel/properties.json
@@ -0,0 +1,54 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "mac-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "mac"
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "mac-cr23-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.mac",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/win-cr23-rel/properties.json b/infra/config/generated/builders/try/win-cr23-rel/properties.json
new file mode 100644
index 0000000..0bc8d8f4
--- /dev/null
+++ b/infra/config/generated/builders/try/win-cr23-rel/properties.json
@@ -0,0 +1,53 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "win-cr23-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "win-cr23-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "jobs": 150,
+    "metrics_project": "chromium-reclient-metrics"
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.win",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 542a7a9..416cc70 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2725,6 +2725,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/linux-cr23-rel"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/linux-dawn-rel"
         includable_only: true
       }
@@ -3452,6 +3456,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/mac-cr23-rel"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/mac-dawn-rel"
         includable_only: true
       }
@@ -3924,6 +3932,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/win-cr23-rel"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/win-dawn-rel"
         includable_only: true
       }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index fb95c7be..6a15b5d0 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -24977,7 +24977,8 @@
         '      "tools/android/avd/proto/creation/generic_android32_foldable.textpb",'
         '      "tools/android/avd/proto/creation/generic_playstore_android32_foldable.textpb",'
         '      "tools/android/avd/proto/creation/generic_android33.textpb",'
-        '      "tools/android/avd/proto/creation/generic_playstore_android33.textpb"'
+        '      "tools/android/avd/proto/creation/generic_playstore_android33.textpb",'
+        '      "tools/android/avd/proto/creation/generic_androidu.textpb"'
         '    ],'
         '    "gclient_apply_config": ['
         '      "android"'
@@ -37368,6 +37369,91 @@
       }
     }
     builders {
+      name: "linux-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/ci/linux-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "linux-extended-tracing-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -42252,6 +42338,89 @@
       }
     }
     builders {
+      name: "mac-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Mac-12"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/ci/mac-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "mac-fieldtrial-tester"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -46522,6 +46691,89 @@
       }
     }
     builders {
+      name: "win-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:win-cr23-rel"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Windows-10"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/ci/win-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "win-fieldtrial-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:win-fieldtrial-rel"
@@ -74616,6 +74868,96 @@
       }
     }
     builders {
+      name: "linux-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/linux-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.linux",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "linux-dawn-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:linux-dawn-rel"
@@ -81152,6 +81494,95 @@
       }
     }
     builders {
+      name: "mac-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Mac"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:1"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/mac-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.mac",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "mac-dawn-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:mac-dawn-rel"
@@ -86659,6 +87090,96 @@
       }
     }
     builders {
+      name: "win-cr23-rel"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Windows-10"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/win-cr23-rel/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.win",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "win-dawn-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:win-dawn-rel"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 00591d47..0d3eb67 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -9434,6 +9434,21 @@
     short_name: "winss"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/linux-cr23-rel"
+    category: "cr23"
+    short_name: "lnx"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.ci/mac-cr23-rel"
+    category: "cr23"
+    short_name: "mac"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.ci/win-cr23-rel"
+    category: "cr23"
+    short_name: "win"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/android-fieldtrial-rel"
     category: "android"
   }
@@ -11283,6 +11298,11 @@
     short_name: "asn"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/Mac FYI Experimental Release (Apple M1)"
+    category: "Mac|Apple"
+    short_name: "exp"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/Mac FYI Release (Apple M1)"
     category: "Mac|Apple"
     short_name: "rel"
@@ -18011,6 +18031,9 @@
     name: "buildbucket/luci.chromium.try/linux-code-coverage"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/linux-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-dawn-rel"
   }
   builders {
@@ -18224,6 +18247,9 @@
     name: "buildbucket/luci.chromium.try/mac-code-coverage"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/mac-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/mac-dawn-rel"
   }
   builders {
@@ -18407,6 +18433,9 @@
     name: "buildbucket/luci.chromium.try/win-celab-try-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/win-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/win-dawn-rel"
   }
   builders {
@@ -19172,6 +19201,9 @@
     name: "buildbucket/luci.chromium.try/linux-code-coverage"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/linux-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/linux-dcheck-off-rel"
   }
   builders {
@@ -19456,6 +19488,9 @@
     name: "buildbucket/luci.chromium.try/mac-code-coverage"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/mac-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/mac-fieldtrial-tester"
   }
   builders {
@@ -19703,6 +19738,9 @@
     name: "buildbucket/luci.chromium.try/win-celab-try-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/win-cr23-rel"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/win-fieldtrial-rel"
   }
   builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 810d8fc3..eb8a813e 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -4957,6 +4957,15 @@
   }
 }
 job {
+  id: "linux-cr23-rel"
+  realm: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "linux-cr23-rel"
+  }
+}
+job {
   id: "linux-extended-tracing-rel"
   realm: "ci"
   buildbucket {
@@ -5528,6 +5537,16 @@
   }
 }
 job {
+  id: "mac-cr23-rel"
+  realm: "ci"
+  schedule: "0 11 * * *"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "mac-cr23-rel"
+  }
+}
+job {
   id: "mac-fieldtrial-tester"
   realm: "ci"
   buildbucket {
@@ -5990,6 +6009,15 @@
   }
 }
 job {
+  id: "win-cr23-rel"
+  realm: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "win-cr23-rel"
+  }
+}
+job {
   id: "win-fieldtrial-rel"
   realm: "ci"
   buildbucket {
@@ -6625,6 +6653,7 @@
   triggers: "linux-chromeos-annotator-rel"
   triggers: "linux-chromeos-dbg"
   triggers: "linux-chromeos-rel"
+  triggers: "linux-cr23-rel"
   triggers: "linux-extended-tracing-rel"
   triggers: "linux-fieldtrial-rel"
   triggers: "linux-gcc-rel"
@@ -6668,6 +6697,7 @@
   triggers: "mac-arm64-on-arm64-rel"
   triggers: "mac-arm64-rel"
   triggers: "mac-backuprefptr-x64-fyi-rel"
+  triggers: "mac-cr23-rel"
   triggers: "mac-intel-on-arm64-rel"
   triggers: "mac-lsan-fyi-rel"
   triggers: "mac-official"
@@ -6690,6 +6720,7 @@
   triggers: "win-backuprefptr-x64-fyi-rel"
   triggers: "win-backuprefptr-x86-fyi-rel"
   triggers: "win-build-perf-developer"
+  triggers: "win-cr23-rel"
   triggers: "win-fieldtrial-rel"
   triggers: "win-official"
   triggers: "win-presubmit"
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 4f7266c..da49aa0 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -48,6 +48,8 @@
             "win32",
             "backuprefptr",
             "buildperf",
+            # TODO(crbug.com/1441164): remove after CR2023 launch.
+            "cr23",
         ],
         "code_coverage": consoles.ordering(
             short_names = ["and", "ann", "lnx", "lcr", "jcr", "mac"],
@@ -2698,3 +2700,73 @@
     notifies = ["annotator-rel"],
     reclient_jobs = reclient.jobs.LOW_JOBS_FOR_CI,
 )
+
+# TODO(crbug.com/1441164): ChromeRefresh2023 builders. Remove after launch.
+ci.builder(
+    name = "linux-cr23-rel",
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = ["mb"],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+        ),
+        build_gs_bucket = "chromium-fyi-archive",
+    ),
+    os = os.LINUX_BIONIC,
+    console_view_entry = consoles.console_view_entry(
+        category = "cr23",
+        short_name = "lnx",
+    ),
+)
+
+ci.builder(
+    name = "win-cr23-rel",
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = ["mb"],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+        ),
+    ),
+    os = os.WINDOWS_10,
+    console_view_entry = consoles.console_view_entry(
+        category = "cr23",
+        short_name = "win",
+    ),
+)
+
+fyi_mac_builder(
+    name = "mac-cr23-rel",
+    # Builderless Mac machines are at full capacity.
+    # For now, run at 11AM UTC, once a day.
+    # TODO(crbug.com/1422735): use thin_tester once FYI bots have
+    # dedicated compilators.
+    schedule = "0 11 * * *",
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = ["mb"],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.MAC,
+        ),
+    ),
+    builderless = True,
+    cores = None,
+    os = os.MAC_DEFAULT,
+    console_view_entry = consoles.console_view_entry(
+        category = "cr23",
+        short_name = "mac",
+    ),
+)
diff --git a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
index 1dbf38d..aad41b6c 100644
--- a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
@@ -857,10 +857,10 @@
         run_tests_serially = True,
     ),
     # Uncomment this entry when this experimental tester is actually in use.
-    # console_view_entry = consoles.console_view_entry(
-    #     category = "Mac|Apple",
-    #     short_name = "exp",
-    # ),
+    console_view_entry = consoles.console_view_entry(
+        category = "Mac|Apple",
+        short_name = "exp",
+    ),
     list_view = "chromium.gpu.experimental",
 )
 
diff --git a/infra/config/subprojects/chromium/ci/chromium.infra.star b/infra/config/subprojects/chromium/ci/chromium.infra.star
index 3b5ef0e..c96b5fd 100644
--- a/infra/config/subprojects/chromium/ci/chromium.infra.star
+++ b/infra/config/subprojects/chromium/ci/chromium.infra.star
@@ -124,6 +124,7 @@
                 "tools/android/avd/proto/creation/generic_playstore_android32_foldable.textpb",
                 "tools/android/avd/proto/creation/generic_android33.textpb",
                 "tools/android/avd/proto/creation/generic_playstore_android33.textpb",
+                "tools/android/avd/proto/creation/generic_androidu.textpb",
             ],
             "gclient_config": "chromium",
             "gclient_apply_config": ["android"],
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index 3934bb4..dac2ea4f 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -753,3 +753,8 @@
         experiment_percentage = 5,
     ),
 )
+
+try_.builder(
+    name = "linux-cr23-rel",
+    mirrors = ["ci/linux-cr23-rel"],
+)
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
index 9823f78..26ff1d8 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -602,3 +602,8 @@
         ],
     ),
 )
+
+try_.builder(
+    name = "mac-cr23-rel",
+    mirrors = ["ci/mac-cr23-rel"],
+)
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
index 98960f9a..2131739 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -311,3 +311,8 @@
         ],
     ),
 )
+
+try_.builder(
+    name = "win-cr23-rel",
+    mirrors = ["ci/win-cr23-rel"],
+)
diff --git a/ios/chrome/app/resources/BUILD.gn b/ios/chrome/app/resources/BUILD.gn
index 7ddeab12..5a658ea 100644
--- a/ios/chrome/app/resources/BUILD.gn
+++ b/ios/chrome/app/resources/BUILD.gn
@@ -98,7 +98,6 @@
       "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
       "$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
       "$root_gen_dir/content/content_resources.pak",
-      "$root_gen_dir/content/dev_ui_content_resources.pak",
       "$root_gen_dir/content/quota_internals_resources.pak",
       "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
       "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
@@ -110,7 +109,6 @@
     deps += [
       "//base/tracing/protos:chrome_track_event_resources",
       "//content:content_resources",
-      "//content:dev_ui_content_resources",
       "//content/browser/resources:resources",
       "//content/browser/resources/media:resources",
       "//content/browser/webrtc/resources",
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index 572eb4c..f22edcce 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -86,6 +86,7 @@
     "//base",
     "//components/autofill/core/browser",
     "//components/autofill/ios/browser",
+    "//ios/chrome/browser/autofill/bottom_sheet",
     "//ios/chrome/browser/shared/ui/util",
     "//ios/web/public",
     "//ios/web/public/js_messaging",
diff --git a/ios/chrome/browser/autofill/bottom_sheet/BUILD.gn b/ios/chrome/browser/autofill/bottom_sheet/BUILD.gn
index 7cd66778..85b1003 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/BUILD.gn
+++ b/ios/chrome/browser/autofill/bottom_sheet/BUILD.gn
@@ -15,6 +15,7 @@
   deps = [
     ":bottom_sheet_ts",
     "//base",
+    "//components/autofill/core/browser",
     "//components/autofill/core/common",
     "//components/autofill/ios/form_util",
     "//components/password_manager/core/common:features",
diff --git a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.h b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.h
index 92ce0b1..36d282e 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.h
+++ b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.h
@@ -26,6 +26,11 @@
   // the field that had originally triggered the bottom sheet.
   void DetachListenersAndRefocus(web::WebFrame* frame);
 
+  // This function will result in detaching listeners from the username
+  // and password fields, which will prevent the bottom sheet from showing
+  // up until the form reloads.
+  void DetachListeners(web::WebFrame* frame);
+
  private:
   friend class base::NoDestructor<BottomSheetJavaScriptFeature>;
 
diff --git a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.mm b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.mm
index 1b36274..1244080 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.mm
+++ b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_java_script_feature.mm
@@ -65,3 +65,7 @@
     web::WebFrame* frame) {
   CallJavaScriptFunction(frame, "bottomSheet.detachListenersAndRefocus", {});
 }
+
+void BottomSheetJavaScriptFeature::DetachListeners(web::WebFrame* frame) {
+  CallJavaScriptFunction(frame, "bottomSheet.detachListeners", {});
+}
diff --git a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h
index 40ad3ed..7563de7 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h
+++ b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h
@@ -5,7 +5,9 @@
 #ifndef IOS_CHROME_BROWSER_AUTOFILL_BOTTOM_SHEET_BOTTOM_SHEET_TAB_HELPER_H_
 #define IOS_CHROME_BROWSER_AUTOFILL_BOTTOM_SHEET_BOTTOM_SHEET_TAB_HELPER_H_
 
+#import "components/autofill/core/browser/ui/popup_types.h"
 #import "components/autofill/core/common/unique_ids.h"
+#import "ios/web/public/web_state_observer.h"
 #import "ios/web/public/web_state_user_data.h"
 
 namespace web {
@@ -19,7 +21,8 @@
 
 // TODO(crbug.com/1422361): Rename this class to include the notion of autofill.
 class BottomSheetTabHelper
-    : public web::WebStateUserData<BottomSheetTabHelper> {
+    : public web::WebStateObserver,
+      public web::WebStateUserData<BottomSheetTabHelper> {
  public:
   BottomSheetTabHelper(const BottomSheetTabHelper&) = delete;
   BottomSheetTabHelper& operator=(const BottomSheetTabHelper&) = delete;
@@ -41,6 +44,17 @@
   // Detach the listeners, which will deactivate the bottom sheet.
   void DetachListenersAndRefocus(web::WebFrame* frame);
 
+  // Notification that the keyboard accessory will be shown with a specific type
+  // of suggestions. May be called multiple times before showing the keyboard
+  // accessory.
+  void WillShowKeyboardAccessory(autofill::PopupType suggestionType,
+                                 web::WebFrame* frame);
+
+  // WebStateObserver:
+  void DidFinishNavigation(web::WebState* web_state,
+                           web::NavigationContext* navigation_context) override;
+  void WebStateDestroyed(web::WebState* web_state) override;
+
  private:
   friend class web::WebStateUserData<BottomSheetTabHelper>;
 
@@ -65,6 +79,11 @@
   // The WebState with which this object is associated.
   web::WebState* const web_state_;
 
+  // Whether the bottom sheet is currently enabled. This prevents receiving
+  // async messages or commands to attach listeners once any request to disable
+  // the bottom sheet has been made.
+  bool enabled_;
+
   WEB_STATE_USER_DATA_KEY_DECL();
 };
 
diff --git a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.mm b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.mm
index 706e5277..7b6552bd5 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.mm
+++ b/ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.mm
@@ -15,6 +15,7 @@
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h"
 #import "ios/web/public/js_messaging/script_message.h"
+#import "ios/web/public/navigation/navigation_context.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -34,7 +35,10 @@
         password_account_storage_notice_handler)
     : password_account_storage_notice_handler_(
           password_account_storage_notice_handler),
-      web_state_(web_state) {}
+      web_state_(web_state),
+      enabled_(true) {
+  web_state->AddObserver(this);
+}
 
 // Public methods
 
@@ -47,7 +51,7 @@
 void BottomSheetTabHelper::OnFormMessageReceived(
     const web::ScriptMessage& message) {
   autofill::FormActivityParams params;
-  if (!password_bottom_sheet_commands_handler_ ||
+  if (!enabled_ || !password_bottom_sheet_commands_handler_ ||
       !password_account_storage_notice_handler_ ||
       !autofill::FormActivityParams::FromMessage(message, &params)) {
     return;
@@ -73,7 +77,8 @@
     web::WebFrame* frame) {
   // Verify that the password bottom sheet feature is enabled and that it hasn't
   // been dismissed too many times.
-  if (!base::FeatureList::IsEnabled(
+  if (!enabled_ ||
+      !base::FeatureList::IsEnabled(
           password_manager::features::kIOSPasswordBottomSheet) ||
       HasReachedDismissLimit()) {
     return;
@@ -85,9 +90,43 @@
 }
 
 void BottomSheetTabHelper::DetachListenersAndRefocus(web::WebFrame* frame) {
+  if (!enabled_) {
+    return;
+  }
+
+  enabled_ = false;
   BottomSheetJavaScriptFeature::GetInstance()->DetachListenersAndRefocus(frame);
 }
 
+void BottomSheetTabHelper::WillShowKeyboardAccessory(
+    autofill::PopupType suggestionType,
+    web::WebFrame* frame) {
+  // If the keyboard accessory is being shown with a specific type of suggestion
+  // for which a bottom sheet exists, disable that bottom sheet in order to
+  // provide a consistent experience for the user.
+  if (enabled_ && (suggestionType == autofill::PopupType::kPasswords)) {
+    enabled_ = false;
+    BottomSheetJavaScriptFeature::GetInstance()->DetachListeners(frame);
+  }
+}
+
+// WebStateObserver
+
+void BottomSheetTabHelper::DidFinishNavigation(
+    web::WebState* web_state,
+    web::NavigationContext* navigation_context) {
+  if (navigation_context->IsSameDocument()) {
+    return;
+  }
+
+  // Re-enable the bottom sheet when loading a new page
+  enabled_ = true;
+}
+
+void BottomSheetTabHelper::WebStateDestroyed(web::WebState* web_state) {
+  web_state->RemoveObserver(this);
+}
+
 // Private methods
 
 bool BottomSheetTabHelper::HasReachedDismissLimit() {
diff --git a/ios/chrome/browser/autofill/bottom_sheet/resources/bottom_sheet.ts b/ios/chrome/browser/autofill/bottom_sheet/resources/bottom_sheet.ts
index 64adf61..23c0af01 100644
--- a/ios/chrome/browser/autofill/bottom_sheet/resources/bottom_sheet.ts
+++ b/ios/chrome/browser/autofill/bottom_sheet/resources/bottom_sheet.ts
@@ -82,9 +82,8 @@
 
 /**
  * Removes all listeners and clears the list of observed elements
- * @private
  */
-function detachListeners_(): void {
+function detachListeners(): void {
   for (const element of observedElements_) {
     element.removeEventListener('focus', focusEventHandler_, true);
   }
@@ -115,7 +114,7 @@
 function detachListenersAndRefocus(): void {
   // If the form was dismissed, we don't need to show it anymore on this page,
   // so remove the event listeners.
-  detachListeners_();
+  detachListeners();
 
   // Re-focus the previously blurred element
   if (lastBlurredElement_) {
@@ -125,5 +124,6 @@
 
 gCrWeb.bottomSheet = {
   attachListeners,
-  detachListenersAndRefocus
+  detachListenersAndRefocus,
+  detachListeners
 };
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_handler.h b/ios/chrome/browser/autofill/form_input_accessory_view_handler.h
index e3e206f..b240b52c 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_handler.h
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_handler.h
@@ -5,6 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_
 #define IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_
 
+#import "components/autofill/core/browser/ui/popup_types.h"
 #import "ios/chrome/browser/autofill/form_input_navigator.h"
 
 namespace web {
@@ -20,6 +21,11 @@
 // Sets the frameId of the frame containing the form with the latest focus.
 - (void)setLastFocusFormActivityWebFrameID:(NSString*)frameID;
 
+// Notification that the keyboard accessory will be shown with a specific type
+// of suggestions. May be called multiple times before showing the keyboard
+// accessory.
+- (void)willShowKeyboardAccessory:(autofill::PopupType)suggestionType;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_HANDLER_H_
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_handler.mm b/ios/chrome/browser/autofill/form_input_accessory_view_handler.mm
index 79155e09..b69bd75d 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_handler.mm
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_handler.mm
@@ -11,6 +11,7 @@
 #import "base/notreached.h"
 #import "base/strings/sys_string_conversions.h"
 #import "components/autofill/ios/browser/suggestion_controller_java_script_feature.h"
+#import "ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/web_state.h"
@@ -165,6 +166,21 @@
   _lastFocusFormActivityWebFrameID = frameID;
 }
 
+- (void)willShowKeyboardAccessory:(autofill::PopupType)suggestionType {
+  if (!_webState) {
+    return;
+  }
+
+  web::WebFrame* frame = [self webFrame];
+
+  if (frame) {
+    BottomSheetTabHelper* bottomSheetTabHelper =
+        BottomSheetTabHelper::FromWebState(_webState);
+    CHECK(bottomSheetTabHelper);
+    bottomSheetTabHelper->WillShowKeyboardAccessory(suggestionType, frame);
+  }
+}
+
 // Attempts to execute/tap/send-an-event-to the iOS built-in "next" and
 // "previous" form assist controls. Returns NO if this attempt failed, YES
 // otherwise. [HACK] Because the buttons on the assist controls can change any
@@ -254,11 +270,7 @@
     return;
   }
 
-  web::WebFramesManager* framesManager =
-      autofill::SuggestionControllerJavaScriptFeature::GetInstance()
-          ->GetWebFramesManager(_webState);
-  web::WebFrame* frame = framesManager->GetFrameWithId(
-      base::SysNSStringToUTF8(_lastFocusFormActivityWebFrameID));
+  web::WebFrame* frame = [self webFrame];
 
   if (!frame) {
     completionHandler(false, false);
@@ -294,11 +306,7 @@
   if (!performedAction && _webState) {
     // We could not find the built-in form assist controls, so try to focus
     // the next or previous control using JavaScript.
-    web::WebFramesManager* framesManager =
-        autofill::SuggestionControllerJavaScriptFeature::GetInstance()
-            ->GetWebFramesManager(_webState);
-    web::WebFrame* frame = framesManager->GetFrameWithId(
-        base::SysNSStringToUTF8(_lastFocusFormActivityWebFrameID));
+    web::WebFrame* frame = [self webFrame];
 
     if (frame) {
       autofill::SuggestionControllerJavaScriptFeature::GetInstance()
@@ -316,11 +324,7 @@
   if (!performedAction && _webState) {
     // We could not find the built-in form assist controls, so try to focus
     // the next or previous control using JavaScript.
-    web::WebFramesManager* framesManager =
-        autofill::SuggestionControllerJavaScriptFeature::GetInstance()
-            ->GetWebFramesManager(_webState);
-    web::WebFrame* frame = framesManager->GetFrameWithId(
-        base::SysNSStringToUTF8(_lastFocusFormActivityWebFrameID));
+    web::WebFrame* frame = [self webFrame];
 
     if (frame) {
       autofill::SuggestionControllerJavaScriptFeature::GetInstance()
@@ -329,4 +333,13 @@
   }
 }
 
+// Attempts to fetch the frame object from its id. May return nil.
+- (web::WebFrame*)webFrame {
+  web::WebFramesManager* framesManager =
+      autofill::SuggestionControllerJavaScriptFeature::GetInstance()
+          ->GetWebFramesManager(_webState);
+  return framesManager->GetFrameWithId(
+      base::SysNSStringToUTF8(_lastFocusFormActivityWebFrameID));
+}
+
 @end
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn
index e8c9096..a84a725 100644
--- a/ios/chrome/browser/passwords/BUILD.gn
+++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -241,6 +241,7 @@
     "//ios/chrome/browser/autofill",
     "//ios/chrome/browser/autofill/bottom_sheet",
     "//ios/chrome/browser/credential_provider_promo:features",
+    "//ios/chrome/browser/passwords:store_factory",
     "//ios/chrome/browser/passwords/test",
     "//ios/chrome/browser/shared/model/browser/test:test_support",
     "//ios/chrome/browser/shared/model/browser_state",
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_check_manager_unittest.mm b/ios/chrome/browser/passwords/ios_chrome_password_check_manager_unittest.mm
index c5d1a721..2b04be1 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_check_manager_unittest.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_check_manager_unittest.mm
@@ -19,6 +19,7 @@
 #import "base/test/scoped_feature_list.h"
 #import "base/time/time.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/password_manager/core/browser/affiliation/fake_affiliation_service.h"
 #import "components/password_manager/core/browser/bulk_leak_check_service.h"
 #import "components/password_manager/core/browser/mock_bulk_leak_check_service.h"
 #import "components/password_manager/core/browser/password_form.h"
@@ -28,6 +29,7 @@
 #import "components/password_manager/core/common/password_manager_pref_names.h"
 #import "components/prefs/pref_registry_simple.h"
 #import "components/prefs/testing_pref_service.h"
+#import "ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_bulk_leak_check_service_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
@@ -125,6 +127,13 @@
         base::BindRepeating(
             &password_manager::BuildPasswordStore<web::BrowserState,
                                                   TestPasswordStore>));
+    builder.AddTestingFactory(
+        IOSChromeAffiliationServiceFactory::GetInstance(),
+        base::BindRepeating(base::BindLambdaForTesting([](web::BrowserState*) {
+          return std::unique_ptr<KeyedService>(
+              std::make_unique<password_manager::FakeAffiliationService>());
+        })));
+
     browser_state_ = builder.Build();
     bulk_leak_check_service_ = static_cast<MockBulkLeakCheckService*>(
         IOSChromeBulkLeakCheckServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm
index 43069d2..6f4bbda 100644
--- a/ios/chrome/browser/passwords/password_controller.mm
+++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -571,8 +571,11 @@
 - (void)attachListenersForBottomSheet:
             (const std::vector<autofill::FieldRendererId>&)rendererIds
                               inFrame:(web::WebFrame*)frame {
-  BottomSheetTabHelper::FromWebState(_webState)->AttachListeners(rendererIds,
-                                                                 frame);
+  BottomSheetTabHelper* bottomSheetTabHelper =
+      BottomSheetTabHelper::FromWebState(_webState);
+  if (bottomSheetTabHelper) {
+    bottomSheetTabHelper->AttachListeners(rendererIds, frame);
+  }
 }
 
 - (BOOL)shouldShowAccountStorageNotice {
diff --git a/ios/chrome/browser/passwords/password_controller_egtest.mm b/ios/chrome/browser/passwords/password_controller_egtest.mm
index cf27ba75..59c3abe 100644
--- a/ios/chrome/browser/passwords/password_controller_egtest.mm
+++ b/ios/chrome/browser/passwords/password_controller_egtest.mm
@@ -241,8 +241,8 @@
                      IDS_IOS_PASSWORDS_ACCOUNT_STORAGE_NOTICE_BUTTON_TEXT))]
       performAction:grey_tap()];
 
-  [ChromeEarlGrey waitForUIElementToAppearWithMatcher:grey_accessibilityID(
-                                                          @"user ••••••••")];
+  [ChromeEarlGrey
+      waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")];
 
   [[EarlGrey
       selectElementWithMatcher:grey_accessibilityLabel(l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
index 1f28ffc2..32e647f8 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
@@ -528,6 +528,16 @@
 
   // If suggestions are enabled, update `currentProvider`.
   self.currentProvider = provider;
+
+  // Notify that we are showing the keyboard accessory for a given type of
+  // suggestion. Note that this is called here so that it does get called when
+  // the keyboard accessory is about to show a set of suggestions, but this
+  // notification should NOT get propagated if the suggestions are accessed
+  // by clicking the key icon on the keyboard. This is specifically for the
+  // keyboard accessory.
+  [self.formNavigationHandler
+      willShowKeyboardAccessory:provider.suggestionType];
+
   // Post it to the consumer.
   self.consumer.suggestionType = provider.suggestionType;
   self.consumer.currentFieldId = _lastSeenParams.unique_field_id;
diff --git a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
index 067c348..35465711 100644
--- a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
+++ b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
@@ -348,7 +348,8 @@
 }
 
 // Tests that history.pushState triggers a new detection.
-- (void)testLanguageDetectionWithPushState {
+// TODO(crbug.com/1442963): This test is flaky.
+- (void)FLAKY_testLanguageDetectionWithPushState {
   const GURL URL = web::test::HttpServer::MakeUrl(
       "http://scenarioLanguageDetectionPushState");
   std::map<GURL, std::string> responses;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
index f0e5c30..f5d274f 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -389,6 +389,15 @@
     percent = std::clamp<CGFloat>(
         animatingOffset / ntp_header::kAnimationDistance, 0, 1);
   }
+  if (IsMagicStackEnabled()) {
+    // Update background color of fake toolbar if stuck to top of NTP so that it
+    // has a non-clear background that matches the NTP background. Otherwise,
+    // return to clear background.
+    self.fakeToolbar.backgroundColor =
+        percent == 1.0f
+            ? [UIColor colorNamed:@"ntp_background_light_mode_only_color"]
+            : [UIColor clearColor];
+  }
   return percent;
 }
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
index 2c08e50..579a20c 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -136,6 +136,9 @@
 // constraints are not set before the views have been added to view hierarchy.
 @property(nonatomic, assign) BOOL viewDidFinishLoading;
 
+// YES if the NTP is in the middle of animating an omnibox focus.
+@property(nonatomic, assign) BOOL isAnimatingOmniboxFocus;
+
 @end
 
 @implementation NewTabPageViewController {
@@ -399,6 +402,18 @@
 #pragma mark - Public
 
 - (void)focusOmnibox {
+  // Do nothing if the omnibox is already focused or is in the middle of a
+  // focus. This prevents `collectionShiftingOffset` from being reset to close
+  // to 0, which would result in the defocus animation not returning to the top
+  // of the NTP if that was the original position.
+  // This is relevant beacuse the omnibox logic signals the NTP to focus the
+  // omnibox when it becomes the keyboard first responder, but that happens
+  // during the NTP focus animation, which results in -focusOmnibox being called
+  // twice.
+  if (self.omniboxFocused || self.isAnimatingOmniboxFocus) {
+    return;
+  }
+
   // If the feed is meant to be visible and its contents have not loaded yet,
   // then any omnibox focus animations (i.e. opening app from search widget
   // action) needs to wait until it is ready. viewDidAppear: currently serves as
@@ -897,9 +912,11 @@
     strongSelf.disableScrollAnimation = NO;
     [strongSelf.headerViewController
         completeHeaderFakeOmniboxFocusAnimationWithFinalPosition:finalPosition];
+    strongSelf.isAnimatingOmniboxFocus = NO;
   }];
 
   self.animator.interruptible = YES;
+  self.isAnimatingOmniboxFocus = YES;
   [self.animator startAnimation];
 }
 
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_unittest.mm
index 3814377..f7dffbc 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_mediator_unittest.mm
@@ -31,6 +31,7 @@
 using autofill_address_profile_infobar_overlays::
     SaveAddressProfileModalRequestConfig;
 using save_address_profile_infobar_modal_responses::CancelViewAction;
+using save_address_profile_infobar_modal_responses::EditedProfileSaveAction;
 using save_address_profile_infobar_modal_responses::
     LegacyEditedProfileSaveAction;
 using save_address_profile_infobar_modal_responses::NoThanksViewAction;
@@ -41,6 +42,7 @@
   SaveAddressProfileInfobarModalOverlayMediatorTest()
       : callback_installer_(&callback_receiver_,
                             {LegacyEditedProfileSaveAction::ResponseSupport(),
+                             EditedProfileSaveAction::ResponseSupport(),
                              CancelViewAction::ResponseSupport(),
                              NoThanksViewAction::ResponseSupport()}),
         mediator_delegate_(
@@ -126,6 +128,17 @@
   [mediator_ saveEditedProfileWithData:@{}.mutableCopy];
 }
 
+// Tests that calling saveEditedProfileWithProfileData: triggers a
+// EditedProfileSaveAction response.
+TEST_F(SaveAddressProfileInfobarModalOverlayMediatorTest, EditAction) {
+  autofill::AutofillProfile profile;
+  EXPECT_CALL(callback_receiver_,
+              DispatchCallback(request_.get(),
+                               EditedProfileSaveAction::ResponseSupport()));
+  OCMExpect([mediator_delegate_ stopOverlayForMediator:mediator_]);
+  [mediator_ saveEditedProfileWithProfileData:&profile];
+}
+
 // Tests that calling dismissInfobarModal triggers a CancelViewAction response.
 TEST_F(SaveAddressProfileInfobarModalOverlayMediatorTest, CancelAction) {
   EXPECT_CALL(
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
index d2510d2..e061cdce 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
@@ -21,16 +21,18 @@
     "//components/autofill/ios/browser",
     "//components/autofill/ios/form_util",
     "//components/password_manager/core/browser",
-    "//components/password_manager/ios:password_manager_feature_header",
+    "//components/password_manager/ios",
     "//components/prefs",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/autofill",
     "//ios/chrome/browser/autofill/bottom_sheet",
+    "//ios/chrome/browser/autofill/manual_fill",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/default_browser:utils",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/passwords",
     "//ios/chrome/browser/passwords:password_controller_delegate",
+    "//ios/chrome/browser/passwords:passwords",
     "//ios/chrome/browser/prefs:pref_names",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/model/browser",
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
index 49f8211..24c249e9 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
@@ -4,7 +4,9 @@
 
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.h"
 
+#import "components/autofill/ios/browser/form_suggestion.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/password_manager/core/browser/ui/credential_ui_entry.h"
 #import "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/passwords/ios_chrome_account_password_store_factory.h"
@@ -13,10 +15,13 @@
 #import "ios/chrome/browser/passwords/password_controller_delegate.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/scoped_password_suggestion_bottom_sheet_reauth_module_override.h"
 #import "ios/chrome/common/ui/reauthentication/reauthentication_module.h"
+#import "ios/web/public/web_state.h"
+#import "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -27,10 +32,6 @@
 @interface PasswordSuggestionBottomSheetCoordinator () {
   // The password controller delegate used to open the password manager.
   id<PasswordControllerDelegate> _passwordControllerDelegate;
-
-  // Service which gives us a view on users' saved passwords.
-  std::unique_ptr<password_manager::SavedPasswordsPresenter>
-      _savedPasswordsPresenter;
 }
 
 // This mediator is used to fetch data related to the bottom sheet.
@@ -60,14 +61,18 @@
 
     ChromeBrowserState* browserState =
         browser->GetBrowserState()->GetOriginalChromeBrowserState();
-    _savedPasswordsPresenter =
-        std::make_unique<password_manager::SavedPasswordsPresenter>(
-            IOSChromeAffiliationServiceFactory::GetForBrowserState(
-                browserState),
-            IOSChromePasswordStoreFactory::GetForBrowserState(
-                browserState, ServiceAccessType::EXPLICIT_ACCESS),
-            IOSChromeAccountPasswordStoreFactory::GetForBrowserState(
-                browserState, ServiceAccessType::EXPLICIT_ACCESS));
+
+    auto profilePasswordStore =
+        IOSChromePasswordStoreFactory::GetForBrowserState(
+            self.browser->GetBrowserState(),
+            ServiceAccessType::EXPLICIT_ACCESS);
+    auto accountPasswordStore =
+        IOSChromeAccountPasswordStoreFactory::GetForBrowserState(
+            self.browser->GetBrowserState(),
+            ServiceAccessType::EXPLICIT_ACCESS);
+
+    WebStateList* webStateList = browser->GetWebStateList();
+    const GURL& URL = webStateList->GetActiveWebState()->GetLastCommittedURL();
 
     self.reauthModule =
         ScopedPasswordSuggestionBottomSheetReauthModuleOverride::instance
@@ -75,15 +80,16 @@
                   ->module
             : [[ReauthenticationModule alloc] init];
     self.mediator = [[PasswordSuggestionBottomSheetMediator alloc]
-           initWithWebStateList:browser->GetWebStateList()
-                  faviconLoader:IOSChromeFaviconLoaderFactory::
-                                    GetForBrowserState(browserState)
-                    prefService:browserState->GetPrefs()
-                         params:params
-        savedPasswordsPresenter:_savedPasswordsPresenter.get()
-                   reauthModule:_reauthModule];
+        initWithWebStateList:webStateList
+               faviconLoader:IOSChromeFaviconLoaderFactory::GetForBrowserState(
+                                 browserState)
+                 prefService:browserState->GetPrefs()
+                      params:params
+                reauthModule:_reauthModule
+                         URL:URL
+        profilePasswordStore:profilePasswordStore
+        accountPasswordStore:accountPasswordStore];
     self.viewController.delegate = self.mediator;
-
     self.mediator.consumer = self.viewController;
   }
   return self;
@@ -117,8 +123,27 @@
 #pragma mark - PasswordSuggestionBottomSheetHandler
 
 - (void)displayPasswordManager {
+  [self.baseViewController.presentedViewController
+      dismissViewControllerAnimated:NO
+                         completion:nil];
+
   [_mediator logExitReason:kShowPasswordManager];
   [_passwordControllerDelegate displaySavedPasswordList];
 }
 
+- (void)displayPasswordDetailsForFormSuggestion:
+    (FormSuggestion*)formSuggestion {
+  [self.baseViewController.presentedViewController
+      dismissViewControllerAnimated:NO
+                         completion:nil];
+
+  absl::optional<password_manager::CredentialUIEntry> credential =
+      [self.mediator getCredentialForFormSuggestion:formSuggestion];
+  if (credential.has_value()) {
+    [_passwordControllerDelegate
+        showPasswordDetailsForCredential:credential.value()];
+  }
+  // TODO(crbug.com/1422344): Add metric for when the credential is nil.
+}
+
 @end
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_delegate.h b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_delegate.h
index 9abe9bc3..b23eed9c 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_delegate.h
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_delegate.h
@@ -23,11 +23,9 @@
 // Disables future refocus requests.
 - (void)disableRefocus;
 
-// Loads the favicon associated with the provided index path.
-// Defaults to the globe symbol if no URL is found.
-- (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath
-           faviconBlockHandler:(FaviconLoader::FaviconAttributesCompletionBlock)
-                                   faviconLoadedBlock;
+// Loads the favicon for cell. Defaults to the globe symbol if the URL is empty.
+- (void)loadFaviconWithBlockHandler:
+    (FaviconLoader::FaviconAttributesCompletionBlock)faviconLoadedBlock;
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_PASSWORDS_BOTTOM_SHEET_PASSWORD_SUGGESTION_BOTTOM_SHEET_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_handler.h b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_handler.h
index e223c69..9dfbd57c 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_handler.h
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_handler.h
@@ -5,12 +5,17 @@
 #ifndef IOS_CHROME_BROWSER_UI_PASSWORDS_BOTTOM_SHEET_PASSWORD_SUGGESTION_BOTTOM_SHEET_HANDLER_H_
 #define IOS_CHROME_BROWSER_UI_PASSWORDS_BOTTOM_SHEET_PASSWORD_SUGGESTION_BOTTOM_SHEET_HANDLER_H_
 
+@class FormSuggestion;
+
 // Handler for the passwords bottom sheet's context menu.
 @protocol PasswordSuggestionBottomSheetHandler
 
 // Displays the password manager menu.
 - (void)displayPasswordManager;
 
+// Displays the password details menu.
+- (void)displayPasswordDetailsForFormSuggestion:(FormSuggestion*)formSuggestion;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_PASSWORDS_BOTTOM_SHEET_PASSWORD_SUGGESTION_BOTTOM_SHEET_HANDLER_H_
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.h b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.h
index 7ae5f89..5da4150 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.h
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.h
@@ -8,17 +8,23 @@
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_delegate.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_exit_reason.h"
 
+#import "third_party/abseil-cpp/absl/types/optional.h"
+
 namespace autofill {
 struct FormActivityParams;
 }  // namespace autofill
 
 namespace password_manager {
-class SavedPasswordsPresenter;
+struct CredentialUIEntry;
+class PasswordStoreInterface;
 }  // namespace password_manager
 
 class FaviconLoader;
 class PrefService;
 class WebStateList;
+class GURL;
+
+@class FormSuggestion;
 
 @protocol PasswordSuggestionBottomSheetConsumer;
 @protocol ReauthenticationProtocol;
@@ -33,10 +39,14 @@
                        faviconLoader:(FaviconLoader*)faviconLoader
                          prefService:(PrefService*)prefService
                               params:(const autofill::FormActivityParams&)params
-             savedPasswordsPresenter:
-                 (raw_ptr<password_manager::SavedPasswordsPresenter>)
-                     passwordPresenter
-                        reauthModule:(id<ReauthenticationProtocol>)reauthModule;
+                        reauthModule:(id<ReauthenticationProtocol>)reauthModule
+                                 URL:(const GURL&)URL
+                profilePasswordStore:
+                    (scoped_refptr<password_manager::PasswordStoreInterface>)
+                        profilePasswordStore
+                accountPasswordStore:
+                    (scoped_refptr<password_manager::PasswordStoreInterface>)
+                        accountPasswordStore;
 
 // Disconnects the mediator.
 - (void)disconnect;
@@ -44,6 +54,11 @@
 // Whether the mediator has any suggestions for the user.
 - (BOOL)hasSuggestions;
 
+// Return the credential associated with the form suggestion. It is an optional,
+// in case the credential can't be find.
+- (absl::optional<password_manager::CredentialUIEntry>)
+    getCredentialForFormSuggestion:(FormSuggestion*)formSuggestion;
+
 // The bottom sheet suggestions consumer.
 @property(nonatomic, strong) id<PasswordSuggestionBottomSheetConsumer> consumer;
 
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
index d001265..37b2df74 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
@@ -7,12 +7,15 @@
 #import "base/memory/raw_ptr.h"
 #import "base/strings/sys_string_conversions.h"
 #import "components/autofill/ios/form_util/form_activity_params.h"
-#import "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
+#import "components/password_manager/core/browser/password_store_interface.h"
+#import "components/password_manager/core/browser/ui/credential_ui_entry.h"
 #import "components/password_manager/ios/password_manager_java_script_feature.h"
+#import "components/password_manager/ios/shared_password_controller.h"
 #import "components/prefs/pref_service.h"
 #import "ios/chrome/browser/autofill/bottom_sheet/bottom_sheet_tab_helper.h"
 #import "ios/chrome/browser/autofill/form_input_suggestions_provider.h"
 #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
+#import "ios/chrome/browser/autofill/manual_fill/passwords_fetcher.h"
 #import "ios/chrome/browser/default_browser/utils.h"
 #import "ios/chrome/browser/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/model/web_state_list/active_web_state_observation_forwarder.h"
@@ -20,7 +23,6 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_consumer.h"
-#import "ios/chrome/browser/ui/settings/password/saved_passwords_presenter_observer.h"
 #import "ios/chrome/common/ui/favicon/favicon_attributes.h"
 #import "ios/chrome/common/ui/favicon/favicon_constants.h"
 #import "ios/chrome/common/ui/reauthentication/reauthentication_event.h"
@@ -30,6 +32,7 @@
 #import "ios/web/public/web_state.h"
 #import "ios/web/public/web_state_observer_bridge.h"
 #import "ui/base/l10n/l10n_util_mac.h"
+#import "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -42,10 +45,9 @@
 using ReauthenticationEvent::kMissingPasscode;
 using ReauthenticationEvent::kSuccess;
 
-@interface PasswordSuggestionBottomSheetMediator () <
-    WebStateListObserving,
-    CRWWebStateObserver,
-    SavedPasswordsPresenterObserver>
+@interface PasswordSuggestionBottomSheetMediator () <WebStateListObserving,
+                                                     CRWWebStateObserver,
+                                                     PasswordFetcherDelegate>
 
 // The object that provides suggestions while filling forms.
 @property(nonatomic, weak) id<FormInputSuggestionsProvider> suggestionsProvider;
@@ -56,21 +58,26 @@
 // Default globe favicon when no favicon is available.
 @property(nonatomic, readonly) FaviconAttributes* defaultGlobeIconAttributes;
 
+// The password fetcher to query the user profile.
+@property(nonatomic, strong) PasswordFetcher* passwordFetcher;
+
 @end
 
 @implementation PasswordSuggestionBottomSheetMediator {
+  // The interfaces for getting and manipulating a user's saved passwords.
+  scoped_refptr<password_manager::PasswordStoreInterface> _profilePasswordStore;
+  scoped_refptr<password_manager::PasswordStoreInterface> _accountPasswordStore;
+
+  // Origin to fetch passwords for.
+  GURL _URL;
+
   // The WebStateList observed by this mediator and the observer bridge.
   raw_ptr<WebStateList> _webStateList;
   std::unique_ptr<web::WebStateObserverBridge> _observer;
   std::unique_ptr<ActiveWebStateObservationForwarder> _forwarder;
 
-  // A helper object for passing data about saved passwords from a finished
-  // password store request to the PasswordSuggestionBottomSheetViewController.
-  std::unique_ptr<SavedPasswordsPresenterObserverBridge>
-      _passwordsPresenterObserver;
-
-  // Service which gives us a view on users' saved passwords.
-  raw_ptr<password_manager::SavedPasswordsPresenter> _savedPasswordsPresenter;
+  // Vector of credentials related to the current page.
+  std::vector<password_manager::CredentialUIEntry> _credentials;
 
   // Whether the field that triggered the bottom sheet will need to refocus when
   // the bottom sheet is dismissed. Default is true.
@@ -92,14 +99,18 @@
 
 @synthesize defaultGlobeIconAttributes = _defaultGlobeIconAttributes;
 
-- (instancetype)
-       initWithWebStateList:(WebStateList*)webStateList
-              faviconLoader:(FaviconLoader*)faviconLoader
-                prefService:(PrefService*)prefService
-                     params:(const autofill::FormActivityParams&)params
-    savedPasswordsPresenter:
-        (raw_ptr<password_manager::SavedPasswordsPresenter>)passwordPresenter
-               reauthModule:(id<ReauthenticationProtocol>)reauthModule {
+- (instancetype)initWithWebStateList:(WebStateList*)webStateList
+                       faviconLoader:(FaviconLoader*)faviconLoader
+                         prefService:(PrefService*)prefService
+                              params:(const autofill::FormActivityParams&)params
+                        reauthModule:(id<ReauthenticationProtocol>)reauthModule
+                                 URL:(const GURL&)URL
+                profilePasswordStore:
+                    (scoped_refptr<password_manager::PasswordStoreInterface>)
+                        profilePasswordStore
+                accountPasswordStore:
+                    (scoped_refptr<password_manager::PasswordStoreInterface>)
+                        accountPasswordStore {
   if (self = [super init]) {
     _needsRefocus = true;
     _frameId = params.frame_id;
@@ -107,6 +118,10 @@
     _prefService = prefService;
     _reauthenticationModule = reauthModule;
 
+    _profilePasswordStore = profilePasswordStore;
+    _accountPasswordStore = accountPasswordStore;
+    _URL = URL;
+
     _webStateList = webStateList;
     web::WebState* activeWebState = _webStateList->GetActiveWebState();
 
@@ -115,12 +130,6 @@
     _forwarder = std::make_unique<ActiveWebStateObservationForwarder>(
         webStateList, _observer.get());
 
-    _savedPasswordsPresenter = passwordPresenter;
-    _passwordsPresenterObserver =
-        std::make_unique<SavedPasswordsPresenterObserverBridge>(
-            self, _savedPasswordsPresenter);
-    _savedPasswordsPresenter->Init();
-
     if (activeWebState) {
       FormSuggestionTabHelper* tabHelper =
           FormSuggestionTabHelper::FromWebState(activeWebState);
@@ -137,6 +146,14 @@
                 id<FormInputSuggestionsProvider> formInputSuggestionsProvider) {
               self.suggestions = suggestions;
             }];
+
+      // Fetch passwords related to the suggestions.
+      _credentials.clear();
+      self.passwordFetcher = [[PasswordFetcher alloc]
+          initWithProfilePasswordStore:_profilePasswordStore
+                  accountPasswordStore:_accountPasswordStore
+                              delegate:self
+                                   URL:_URL];
     }
   }
   return self;
@@ -146,10 +163,6 @@
 }
 
 - (void)disconnect {
-  DCHECK(_savedPasswordsPresenter);
-  DCHECK(_passwordsPresenterObserver);
-  _savedPasswordsPresenter->RemoveObserver(_passwordsPresenterObserver.get());
-  _passwordsPresenterObserver.reset();
   _prefService = nullptr;
   _faviconLoader = nullptr;
   _forwarder = nullptr;
@@ -161,6 +174,31 @@
   return [self.suggestions count] > 0;
 }
 
+- (absl::optional<password_manager::CredentialUIEntry>)
+    getCredentialForFormSuggestion:(FormSuggestion*)formSuggestion {
+  NSString* username = formSuggestion.value;
+  if ([username containsString:kPasswordFormSuggestionSuffix]) {
+    username = [username
+        stringByReplacingOccurrencesOfString:kPasswordFormSuggestionSuffix
+                                  withString:@""];
+  }
+  auto it = base::ranges::find_if(
+      _credentials,
+      [username](const password_manager::CredentialUIEntry& credential) {
+        CHECK(!credential.facets.empty());
+        for (auto facet : credential.facets) {
+          if ([base::SysUTF16ToNSString(credential.username)
+                  isEqualToString:username]) {
+            return true;
+          }
+        }
+        return false;
+      });
+  return it != _credentials.end()
+             ? absl::optional<password_manager::CredentialUIEntry>(*it)
+             : absl::nullopt;
+}
+
 - (void)logExitReason:(PasswordSuggestionBottomSheetExitReason)exitReason {
   base::UmaHistogramEnumeration("IOS.PasswordBottomSheet.ExitReason",
                                 exitReason);
@@ -234,15 +272,12 @@
   _needsRefocus = false;
 }
 
-- (void)loadFaviconAtIndexPath:(NSIndexPath*)indexPath
-           faviconBlockHandler:(FaviconLoader::FaviconAttributesCompletionBlock)
-                                   faviconLoadedBlock {
+- (void)loadFaviconWithBlockHandler:
+    (FaviconLoader::FaviconAttributesCompletionBlock)faviconLoadedBlock {
   CHECK(_faviconLoader);
-  // Try loading the url's favicon.
-  GURL URL(base::SysNSStringToUTF8([self descriptionAtRow:indexPath.row]));
-  if (!URL.is_empty()) {
+  if (!_URL.is_empty()) {
     _faviconLoader->FaviconForPageUrl(
-        URL, kDesiredMediumFaviconSizePt, kMinFaviconSizePt,
+        _URL, kDesiredMediumFaviconSizePt, kMinFaviconSizePt,
         /*fallback_to_google_server=*/NO, faviconLoadedBlock);
   } else {
     faviconLoadedBlock([self defaultGlobeIconAttributes]);
@@ -290,18 +325,17 @@
   [self.consumer dismiss];
 }
 
-#pragma mark - SavedPasswordsPresenterObserver
+#pragma mark - PasswordFetcherDelegate
 
-- (void)savedPasswordsDidChange {
-  std::vector<password_manager::CredentialUIEntry> savedCredentials =
-      _savedPasswordsPresenter->GetSavedCredentials();
-  if (!savedCredentials.empty()) {
-    // TODO(crbug.com/1422362): Get the CredentialUIEntry associated to this
-    // FormSuggestion. From the saved credentials, we will find the ones
-    // associated with the current suggestions, store them and send that
-    // information to the consumer.
-    [self.consumer setSuggestions:self.suggestions];
+- (void)passwordFetcher:(PasswordFetcher*)passwordFetcher
+      didFetchPasswords:
+          (std::vector<std::unique_ptr<password_manager::PasswordForm>>)
+              passwords {
+  std::vector<password_manager::CredentialUIEntry> credentials;
+  for (const auto& form : passwords) {
+    credentials.push_back(password_manager::CredentialUIEntry(*form));
   }
+  _credentials = credentials;
 }
 
 #pragma mark - Private
@@ -312,12 +346,6 @@
   [self.suggestionsProvider didSelectSuggestion:suggestion];
 }
 
-// Returns the display description at a given row in the table view.
-- (NSString*)descriptionAtRow:(NSInteger)row {
-  FormSuggestion* formSuggestion = [self.suggestions objectAtIndex:row];
-  return formSuggestion.displayDescription;
-}
-
 // Returns the default favicon attributes after making sure they are
 // initialized.
 - (FaviconAttributes*)defaultGlobeIconAttributes {
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
index 2995e45..c1c67645 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
@@ -11,7 +11,6 @@
 #import "components/password_manager/core/browser/affiliation/mock_affiliation_service.h"
 #import "components/password_manager/core/browser/password_manager_test_utils.h"
 #import "components/password_manager/core/browser/test_password_store.h"
-#import "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
 #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
 #import "ios/chrome/browser/favicon/favicon_service_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
@@ -164,8 +163,7 @@
         chrome_browser_state_(TestChromeBrowserState::Builder().Build()) {}
 
   void SetUp() override {
-    GURL url("http://foo.com");
-    test_web_state_->SetCurrentURL(url);
+    test_web_state_->SetCurrentURL(URL());
 
     TestChromeBrowserState::Builder builder;
     builder.AddTestingFactory(ios::FaviconServiceFactory::GetInstance(),
@@ -214,18 +212,16 @@
             IOSChromePasswordStoreFactory::GetForBrowserState(
                 chrome_browser_state_.get(), ServiceAccessType::EXPLICIT_ACCESS)
                 .get()));
-    presenter_ = std::make_unique<password_manager::SavedPasswordsPresenter>(
-        &affiliation_service_, store_, /*accont_store=*/nullptr);
-
     mediator_ = [[PasswordSuggestionBottomSheetMediator alloc]
-           initWithWebStateList:&web_state_list_
-                  faviconLoader:IOSChromeFaviconLoaderFactory::
-                                    GetForBrowserState(
-                                        chrome_browser_state_.get())
-                    prefService:chrome_browser_state_->GetPrefs()
-                         params:params_
-        savedPasswordsPresenter:presenter_.get()
-                   reauthModule:nil];
+        initWithWebStateList:&web_state_list_
+               faviconLoader:IOSChromeFaviconLoaderFactory::GetForBrowserState(
+                                 chrome_browser_state_.get())
+                 prefService:chrome_browser_state_->GetPrefs()
+                      params:params_
+                reauthModule:nil
+                         URL:URL()
+        profilePasswordStore:store_
+        accountPasswordStore:nullptr];
   }
 
   void CreateMediatorWithSuggestions() {
@@ -235,13 +231,14 @@
     CreateMediator();
   }
 
+  GURL URL() { return GURL("http://foo.com"); }
+
   web::WebTaskEnvironment task_environment_;
   std::unique_ptr<web::FakeWebState> test_web_state_;
   FakeWebStateListDelegate web_state_list_delegate_;
   WebStateList web_state_list_;
   std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
   scoped_refptr<password_manager::TestPasswordStore> store_;
-  std::unique_ptr<password_manager::SavedPasswordsPresenter> presenter_;
   id consumer_;
   NSArray<id<FormSuggestionProvider>>* suggestion_providers_;
   autofill::FormActivityParams params_;
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm
index 2d3d9cb..5d6d5f0 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm
@@ -6,7 +6,11 @@
 
 #import "base/mac/foundation_util.h"
 #import "base/memory/raw_ptr.h"
+#import "base/strings/sys_string_conversions.h"
 #import "components/autofill/ios/browser/form_suggestion.h"
+#import "components/password_manager/core/browser/password_ui_utils.h"
+#import "components/password_manager/core/browser/ui/credential_ui_entry.h"
+#import "components/password_manager/ios/shared_password_controller.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.h"
 #import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller.h"
@@ -199,6 +203,8 @@
         PasswordSuggestionBottomSheetViewController* strongSelf = weakSelf;
         if (strongSelf) {
           [menuElements addObject:[strongSelf openPasswordManagerAction]];
+          [menuElements
+              addObject:[strongSelf openPasswordDetailsForIndexPath:indexPath]];
         }
 
         return [UIMenu menuWithTitle:@"" children:menuElements];
@@ -330,12 +336,25 @@
 // Returns the string to display at a given row in the table view.
 - (NSString*)suggestionAtRow:(NSInteger)row {
   FormSuggestion* formSuggestion = [_suggestions objectAtIndex:row];
-  return formSuggestion.value;
+
+  // Removing suffix ' ••••••••' appended to the username in the suggestion.
+  NSString* username = formSuggestion.value;
+  if ([username containsString:kPasswordFormSuggestionSuffix]) {
+    username = [username
+        stringByReplacingOccurrencesOfString:kPasswordFormSuggestionSuffix
+                                  withString:@""];
+  }
+  return username;
 }
 
 // Returns the display description at a given row in the table view.
 - (NSString*)descriptionAtRow:(NSInteger)row {
   FormSuggestion* formSuggestion = [_suggestions objectAtIndex:row];
+  GURL URL(base::SysNSStringToUTF8(formSuggestion.displayDescription));
+  if (!URL.is_empty()) {
+    return base::SysUTF8ToNSString(
+        password_manager::GetShownOrigin(url::Origin::Create(URL)));
+  }
   return formSuggestion.displayDescription;
 }
 
@@ -394,23 +413,13 @@
   DCHECK(cell);
 
   TableViewURLCell* URLCell = base::mac::ObjCCastStrict<TableViewURLCell>(cell);
-
-  // Set the cell identifier to the associated URL, which we use to fetch the
-  // favicon.
-  NSString* cellIdentifier = [self descriptionAtRow:indexPath.row];
-  URLCell.cellUniqueIdentifier = cellIdentifier;
-
   auto faviconLoadedBlock = ^(FaviconAttributes* attributes) {
-    // If the user scrolls quickly, the cell could be reused, so make sure the
-    // favicon still matches the URL used to fetch the favicon (as the favicon
-    // fetch is asynchronous).
-    if ([URLCell.cellUniqueIdentifier isEqualToString:cellIdentifier]) {
-      DCHECK(attributes);
-      [URLCell.faviconView configureWithAttributes:attributes];
-    }
+    DCHECK(attributes);
+    // It doesn't matter which cell the user sees here, all the credentials
+    // listed are for the same page and thus share the same favicon.
+    [URLCell.faviconView configureWithAttributes:attributes];
   };
-  [self.delegate loadFaviconAtIndexPath:indexPath
-                    faviconBlockHandler:faviconLoadedBlock];
+  [self.delegate loadFaviconWithBlockHandler:faviconLoadedBlock];
 }
 
 // Sets the password bottom sheet's table view to full height.
@@ -498,18 +507,19 @@
   [_handler displayPasswordManager];
 }
 
+// Opens the password details for form suggestion.
+- (void)displayPasswordDetailsForFormSuggestion:
+    (FormSuggestion*)formSuggestion {
+  [_handler displayPasswordDetailsForFormSuggestion:formSuggestion];
+}
+
 // Creates the UI action used to open the password manager.
 - (UIAction*)openPasswordManagerAction {
   __weak __typeof(self) weakSelf = self;
   void (^passwordManagerButtonTapHandler)(UIAction*) = ^(UIAction* action) {
     // Open Password Manager.
     [weakSelf.delegate disableRefocus];
-    [weakSelf dismissViewControllerAnimated:NO
-                                 completion:^{
-                                   // Send some message to open the password
-                                   // manager.
-                                   [weakSelf displayPasswordManager];
-                                 }];
+    [weakSelf displayPasswordManager];
   };
   UIImage* keyIcon =
       CustomSymbolWithPointSize(kPasswordSymbol, kSymbolActionPointSize);
@@ -517,8 +527,29 @@
       actionWithTitle:l10n_util::GetNSString(
                           IDS_IOS_PASSWORD_BOTTOM_SHEET_PASSWORD_MANAGER)
                 image:keyIcon
-           identifier:@"kBottomSheetPopupMenuPasswordManagerActionIdentifier"
+           identifier:nil
               handler:passwordManagerButtonTapHandler];
 }
 
+// Creates the UI action used to open the password details for form suggestion
+// at index path.
+- (UIAction*)openPasswordDetailsForIndexPath:(NSIndexPath*)indexPath {
+  __weak __typeof(self) weakSelf = self;
+  FormSuggestion* formSuggestion = [_suggestions objectAtIndex:indexPath.row];
+  void (^showDetailsButtonTapHandler)(UIAction*) = ^(UIAction* action) {
+    // Open Password Details.
+    [weakSelf.delegate disableRefocus];
+    [weakSelf displayPasswordDetailsForFormSuggestion:formSuggestion];
+  };
+
+  UIImage* infoIcon =
+      DefaultSymbolWithPointSize(kInfoCircleSymbol, kSymbolActionPointSize);
+  return
+      [UIAction actionWithTitle:l10n_util::GetNSString(
+                                    IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS)
+                          image:infoIcon
+                     identifier:nil
+                        handler:showDetailsButtonTapHandler];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
index e2e85744a..be6150b 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
@@ -8,6 +8,7 @@
 #import <Foundation/Foundation.h>
 
 #import "base/mac/foundation_util.h"
+#import "base/memory/scoped_refptr.h"
 #import "ios/chrome/browser/ui/settings/password/password_details/password_details.h"
 #import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_delegate.h"
 
@@ -31,15 +32,15 @@
 // Vector of CredentialUIEntry is converted to an array of PasswordDetails and
 // passed to a consumer with the display name (title) for the Password Details
 // view.
-- (instancetype)initWithPasswords:
-                    (const std::vector<password_manager::CredentialUIEntry>&)
-                        credentials
-                      displayName:(NSString*)displayName
-             passwordCheckManager:(IOSChromePasswordCheckManager*)manager
-                      prefService:(PrefService*)prefService
-                      syncService:(syncer::SyncService*)syncService
-                          context:(DetailsContext)context
-                         delegate:(id<PasswordDetailsMediatorDelegate>)delegate
+- (instancetype)
+       initWithPasswords:
+           (const std::vector<password_manager::CredentialUIEntry>&)credentials
+             displayName:(NSString*)displayName
+    passwordCheckManager:(scoped_refptr<IOSChromePasswordCheckManager>)manager
+             prefService:(PrefService*)prefService
+             syncService:(syncer::SyncService*)syncService
+                 context:(DetailsContext)context
+                delegate:(id<PasswordDetailsMediatorDelegate>)delegate
     NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
index a25d542..7913d581 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -91,7 +91,7 @@
   std::vector<CredentialUIEntry> _credentials;
 
   // Password Check manager.
-  raw_ptr<IOSChromePasswordCheckManager> _manager;
+  scoped_refptr<IOSChromePasswordCheckManager> _manager;
 
   // Listens to compromised passwords changes.
   std::unique_ptr<PasswordCheckObserverBridge> _passwordCheckObserver;
@@ -125,7 +125,7 @@
 - (instancetype)
        initWithPasswords:(const std::vector<CredentialUIEntry>&)credentials
              displayName:(NSString*)displayName
-    passwordCheckManager:(IOSChromePasswordCheckManager*)manager
+    passwordCheckManager:(scoped_refptr<IOSChromePasswordCheckManager>)manager
              prefService:(PrefService*)prefService
              syncService:(syncer::SyncService*)syncService
                  context:(DetailsContext)context
@@ -139,10 +139,10 @@
   }
 
   _manager = manager;
+  _passwordCheckObserver =
+      std::make_unique<PasswordCheckObserverBridge>(self, manager.get());
   _credentials = credentials;
   _displayName = displayName;
-  _passwordCheckObserver =
-      std::make_unique<PasswordCheckObserverBridge>(self, manager);
   _context = context;
   _prefService = prefService;
   _syncService = syncService;
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
index d66fbbfe..2f58aba 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
@@ -1816,7 +1816,8 @@
 // storing just about enough passwords to ensure filling more than one page on
 // any device. To limit the effect of (2), custom large scrolling steps are
 // added to the usual scrolling actions.
-- (void)testManyPasswords {
+// TODO(crbug.com/1442985): This test is flaky.
+- (void)FLAKY_testManyPasswords {
   if ([ChromeEarlGrey isIPadIdiom]) {
     // TODO(crbug.com/906551): Enable the test on iPad once the bug is fixed.
     EARL_GREY_TEST_DISABLED(@"Disabled for iPad.");
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index f372c52..79c744a 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -1687,7 +1687,8 @@
 
 // Tests that suggested actions section does not appear in search mode for
 // incognito page.
-- (void)testSuggestedActionsNotAvailableInIncognitoPageSearchMode {
+// TODO(crbug.com/1443003): This test is flaky.
+- (void)FLAKY_testSuggestedActionsNotAvailableInIncognitoPageSearchMode {
   [self loadTestURLsInNewIncognitoTabs];
   [ChromeEarlGreyUI openTabGrid];
 
diff --git a/ios/web/content/BUILD.gn b/ios/web/content/BUILD.gn
index 287fcff3..f5aa0d2 100644
--- a/ios/web/content/BUILD.gn
+++ b/ios/web/content/BUILD.gn
@@ -15,6 +15,8 @@
     "js_messaging/content_web_frame.mm",
     "js_messaging/content_web_frames_manager.h",
     "js_messaging/content_web_frames_manager.mm",
+    "js_messaging/ios_web_message_host_factory.h",
+    "js_messaging/ios_web_message_host_factory.mm",
     "navigation/content_navigation_context.h",
     "navigation/content_navigation_context.mm",
     "navigation/content_navigation_item.h",
diff --git a/ios/web/content/js_messaging/content_web_frames_manager.mm b/ios/web/content/js_messaging/content_web_frames_manager.mm
index 0bf1dab..9c836ef 100644
--- a/ios/web/content/js_messaging/content_web_frames_manager.mm
+++ b/ios/web/content/js_messaging/content_web_frames_manager.mm
@@ -11,6 +11,7 @@
 #import "content/public/browser/page.h"
 #import "content/public/browser/web_contents.h"
 #import "ios/web/content/js_messaging/content_web_frame.h"
+#import "ios/web/content/js_messaging/ios_web_message_host_factory.h"
 #import "ios/web/content/web_state/content_web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -25,7 +26,11 @@
       content_web_state_(content_web_state),
       js_communication_host_(
           std::make_unique<js_injection::JsCommunicationHost>(
-              content_web_state->GetWebContents())) {}
+              content_web_state->GetWebContents())) {
+  auto message_host_factory = std::make_unique<IOSWebMessageHostFactory>();
+  js_communication_host_->AddWebMessageHostFactory(
+      std::move(message_host_factory), u"webkitMessageHandler", {"*"});
+}
 
 ContentWebFramesManager::~ContentWebFramesManager() = default;
 
diff --git a/ios/web/content/js_messaging/ios_web_message_host_factory.h b/ios/web/content/js_messaging/ios_web_message_host_factory.h
new file mode 100644
index 0000000..ce408a6e
--- /dev/null
+++ b/ios/web/content/js_messaging/ios_web_message_host_factory.h
@@ -0,0 +1,32 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_CONTENT_JS_MESSAGING_IOS_WEB_MESSAGE_HOST_FACTORY_H_
+#define IOS_WEB_CONTENT_JS_MESSAGING_IOS_WEB_MESSAGE_HOST_FACTORY_H_
+
+#import "components/js_injection/browser/web_message_host_factory.h"
+
+namespace web {
+
+// An iOS-specific implementation of WebMessageHostFactory, responsible for
+// creating a WebMessageHost when JavaScript sends a message to the browser.
+class IOSWebMessageHostFactory : public js_injection::WebMessageHostFactory {
+ public:
+  // TODO(crbug.com/1423527): Add a listener argument to this constructor. The
+  // listener will be called when messages are received from JavaScript.
+  IOSWebMessageHostFactory();
+  IOSWebMessageHostFactory(const IOSWebMessageHostFactory&) = delete;
+  IOSWebMessageHostFactory& operator=(const IOSWebMessageHostFactory&) = delete;
+  ~IOSWebMessageHostFactory() override;
+
+  // js_injection::WebMessageHostFactory:
+  std::unique_ptr<js_injection::WebMessageHost> CreateHost(
+      const std::string& origin_string,
+      bool is_main_frame,
+      js_injection::WebMessageReplyProxy* proxy) override;
+};
+
+}  // namespace web
+
+#endif  // IOS_WEB_CONTENT_JS_MESSAGING_IOS_WEB_MESSAGE_HOST_FACTORY_H_
diff --git a/ios/web/content/js_messaging/ios_web_message_host_factory.mm b/ios/web/content/js_messaging/ios_web_message_host_factory.mm
new file mode 100644
index 0000000..592af3b
--- /dev/null
+++ b/ios/web/content/js_messaging/ios_web_message_host_factory.mm
@@ -0,0 +1,61 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web/content/js_messaging/ios_web_message_host_factory.h"
+
+#import <string>
+
+#import "base/functional/overloaded.h"
+#import "components/js_injection/browser/js_communication_host.h"
+#import "components/js_injection/browser/web_message.h"
+#import "components/js_injection/browser/web_message_host.h"
+#import "third_party/abseil-cpp/absl/types/variant.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace web {
+namespace {
+
+// Created when a message is received from JavaScript.
+class IOSWebMessageHost : public js_injection::WebMessageHost {
+ public:
+  IOSWebMessageHost(const std::string& origin_string, bool is_main_frame) {}
+
+  ~IOSWebMessageHost() override = default;
+
+  // js_injection::WebMessageHost:
+  void OnPostMessage(
+      std::unique_ptr<js_injection::WebMessage> web_message) override {
+    absl::visit(
+        base::Overloaded{
+            [](const std::u16string& str) {
+              // TODO(crbug.com/1423527): Pass on the extracted message to
+              // feature code.
+              LOG(ERROR) << "webkitMessageHandler received: " << str;
+            },
+            [](const std::unique_ptr<blink::WebMessageArrayBufferPayload>&
+                   array_buffer) {
+              // Do nothing if the received message is not a string.
+            }},
+        web_message->message);
+  }
+};
+
+}  // namespace
+
+IOSWebMessageHostFactory::IOSWebMessageHostFactory() = default;
+
+IOSWebMessageHostFactory::~IOSWebMessageHostFactory() = default;
+
+std::unique_ptr<js_injection::WebMessageHost>
+IOSWebMessageHostFactory::CreateHost(
+    const std::string& origin_string,
+    bool is_main_frame,
+    js_injection::WebMessageReplyProxy* proxy) {
+  return std::make_unique<IOSWebMessageHost>(origin_string, is_main_frame);
+}
+
+}  // namespace web
diff --git a/media/filters/manifest_demuxer.cc b/media/filters/manifest_demuxer.cc
index 92fcf1f..2bc6551 100644
--- a/media/filters/manifest_demuxer.cc
+++ b/media/filters/manifest_demuxer.cc
@@ -65,6 +65,8 @@
 
 ManifestDemuxer::~ManifestDemuxer() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  impl_.reset();
+  chunk_demuxer_.reset();
 }
 
 ManifestDemuxer::ManifestDemuxer(
@@ -140,18 +142,43 @@
 }
 
 void ManifestDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  if (!media_task_runner_->RunsTasksInCurrentSequence()) {
+    media_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&ManifestDemuxer::StartWaitingForSeek,
+                                  weak_factory_.GetWeakPtr(), seek_time));
+    return;
+  }
+  media_time_ = seek_time;
   chunk_demuxer_->StartWaitingForSeek(seek_time);
   impl_->StartWaitingForSeek();
 }
 
 void ManifestDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {
+  if (!media_task_runner_->RunsTasksInCurrentSequence()) {
+    media_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&ManifestDemuxer::CancelPendingSeek,
+                                  weak_factory_.GetWeakPtr(), seek_time));
+    return;
+  }
+
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
-  // TODO(crbug/1266991): In the current implementation, if a seek happens while
-  // another seek is pending, the first seek is allowed to finish before
-  // starting the second seek. As a result, there isn't really a good way to
-  // cancel a pending one, so we don't do anything.
-  NOTIMPLEMENTED();
+
+  // Since cancellation happens from the main thread, it's possible for a
+  // function order to look like:
+  // Main Thread                           | Media Thread
+  // --------------------------------------|-----------------------------------
+  // CancelPendingSeek                     |
+  //         |                             |   CompletePendingSeek
+  //          `----------------------------|-> CancelPendingSeek
+  // so `pending_seek_` might already be called. If `pending_seek_` is still
+  // pending, then canceling the chunk demuxer pending seek should execute
+  // its callback immediately with a success status, and we'd just then be left
+  // waiting for the engine to finish.
+  // TODO(crbug/1266991): Make the engine cancelable as well.
+  if (pending_seek_) {
+    AbortPendingReads();
+    chunk_demuxer_->CancelPendingSeek(seek_time);
+  }
 }
 
 void ManifestDemuxer::Seek(base::TimeDelta time,
@@ -175,28 +202,21 @@
 void ManifestDemuxer::SeekInternal() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
-  // SeekInternal can be delayed and potentially called after a pending event
-  // finishes. Pending events should not restart playback which was stopped
-  // prior to the seek being requested, so we can check that it's still 0.
-  CHECK_EQ(current_playback_rate_, 0);
-
   has_pending_event_ = true;
 
   // Cancel any outstanding events, we don't want them interrupting us.
   cancelable_next_event_.Cancel();
 
-  // ManifestDemuxer::Engine::Seek returns true if it cleared data from
-  // ChunkDemuxer and needs a new call to `OnTimeUpdate`. If this is the
-  // case, ChunkDemuxer won't finish it's seek process until new data is
-  // appended as a result of the player event. However it's possible for that
-  // data to come in chunks, so ChunkDemuxer might think it's ready to finish
-  // it's seek when only some of the data has come in. As a result, we have to
-  // wait for both `OnChunkDemuxerSeeked` AND `OnEngineSeekComplete` to finish.
-  // Each of them will check |seek_waiting_on_engine_|, the first will clear the
-  // flag, and the second will notice the cleared flag and finish the seek
-  // process.
+  // Seek the engine first, since it might clear out data from the chunk demuxer
+  // and reset it into a state where it can accept the correct timestamps. If
+  // ManifestDemuxer::Engine::Seek returns true, then it means that a new fetch
+  // event is required to repopulate the chunk demuxer's buffers.
   seek_waiting_on_engine_ = impl_->Seek(media_time_);
 
+  // Seek the demuxer and signal that we are waiting on it to complete. The seek
+  // won't be finished until the ChunkDemuxer has finished seeking and the
+  // engine is ready.
+  seek_waiting_on_demuxer_ = true;
   chunk_demuxer_->Seek(media_time_,
                        base::BindOnce(&ManifestDemuxer::OnChunkDemuxerSeeked,
                                       weak_factory_.GetWeakPtr()));
@@ -209,18 +229,15 @@
 }
 
 bool ManifestDemuxer::IsSeekable() const {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
-  // The underlying wrapping ChunkDemuxer is seekable.
+  DCHECK(!media_task_runner_->RunsTasksInCurrentSequence());
   return impl_->IsSeekable();
 }
 
 void ManifestDemuxer::Stop() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  cancelable_next_event_.Cancel();
   impl_->Stop();
   chunk_demuxer_->Stop();
-  impl_.reset();
-  chunk_demuxer_.reset();
-  cancelable_next_event_.Cancel();
 }
 
 base::TimeDelta ManifestDemuxer::GetStartTime() const {
@@ -252,7 +269,6 @@
 
 absl::optional<container_names::MediaContainerName>
 ManifestDemuxer::GetContainerForMetrics() const {
-  DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   // TODO(crbug/1266991): Consider how this is used. HLS can involve multiple
   // stream types (mp2t, mp4, etc). Refactor to report something useful.
   return absl::nullopt;
@@ -392,9 +408,10 @@
 
 void ManifestDemuxer::OnChunkDemuxerSeeked(PipelineStatus seek_status) {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  seek_waiting_on_demuxer_ = false;
 
   if (!pending_seek_) {
-    OnError(std::move(seek_status));
+    seek_waiting_on_engine_ = false;
     return;
   }
 
@@ -406,47 +423,33 @@
     return;
   }
 
-  if (seek_waiting_on_engine_) {
-    // If this flag was set, then there is a simultaneous wait for both
-    // OnChunkDemuxerSeeked and OnEngineSeekComplete, and we were called first.
-    // We should set the flag back to false, so that OnEngineSeekComplete can
-    // finish the seeking process.
-    seek_waiting_on_engine_ = false;
-    return;
-  }
-
   // Complete the seek with an ok-status. This function already handles non-ok
   // status results above.
-  CompletePendingSeek();
+  TryCompletePendingSeek();
 }
 
 void ManifestDemuxer::OnEngineSeekComplete(base::TimeDelta delay_time) {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
+  seek_waiting_on_engine_ = false;
 
   if (!pending_seek_) {
-    // OnChunkDemuxerSeeked returned earlier with an error, so we don't have
-    // anything to do. Make sure that the seek waiting flag was cleaned up.
-    CHECK_EQ(seek_waiting_on_engine_, false);
-    return;
-  }
-
-  if (seek_waiting_on_engine_) {
-    // If the flag is still set, we were called before OnChunkDemuxerSeeked.
-    // Set the flag back to false, so that when OnChunkDemuxerSeeked is called,
-    // it will finish up and execute the pending_seek_ callback.
-    seek_waiting_on_engine_ = false;
+    seek_waiting_on_demuxer_ = false;
     return;
   }
 
   // Complete the seek with an ok-status. If the chunk demuxer had failed to
   // seek, it would have already posted the `pending_seek_` call with its
   // failure status.
-  CompletePendingSeek();
+  TryCompletePendingSeek();
 }
 
-void ManifestDemuxer::CompletePendingSeek() {
+void ManifestDemuxer::TryCompletePendingSeek() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
+  if (seek_waiting_on_engine_ || seek_waiting_on_demuxer_) {
+    return;
+  }
+
   CHECK(pending_seek_);
   std::move(pending_seek_).Run(OkStatus());
 
@@ -469,7 +472,7 @@
   if (status == DemuxerStream::Status::kOk) {
     // The entire vector must be checked as timestamps are often out of order.
     for (const auto& buffer : buffers) {
-      if (buffer->timestamp() > media_time_) {
+      if (!buffer->end_of_stream() && buffer->timestamp() > media_time_) {
         media_time_ = buffer->timestamp();
       }
     }
diff --git a/media/filters/manifest_demuxer.h b/media/filters/manifest_demuxer.h
index 0341435..8057635e 100644
--- a/media/filters/manifest_demuxer.h
+++ b/media/filters/manifest_demuxer.h
@@ -130,6 +130,7 @@
   // Allow unit tests to grab the chunk demuxer.
   ChunkDemuxer* GetChunkDemuxerForTesting();
   bool has_pending_seek_for_testing() const { return !pending_seek_.is_null(); }
+  base::TimeDelta get_media_time_for_testing() const { return media_time_; }
   bool has_pending_event_for_testing() const { return has_pending_event_; }
   bool has_next_task_for_testing() const {
     return !cancelable_next_event_.IsCancelled();
@@ -174,7 +175,7 @@
   void SeekInternal();
   void OnChunkDemuxerSeeked(PipelineStatus seek_status);
   void OnEngineSeekComplete(base::TimeDelta delay_time);
-  void CompletePendingSeek();
+  void TryCompletePendingSeek();
 
   // Allows for both the chunk demuxer and the engine to be required for
   // initialization.
@@ -221,6 +222,7 @@
 
   // Flag for the two-cb wait for finishing a seek.
   bool seek_waiting_on_engine_ = false;
+  bool seek_waiting_on_demuxer_ = false;
 
   // Pending an event. Don't trigger a new event chain while one is in
   // progress.
diff --git a/media/filters/manifest_demuxer_unittest.cc b/media/filters/manifest_demuxer_unittest.cc
index 932f4e1..4b7f2a50 100644
--- a/media/filters/manifest_demuxer_unittest.cc
+++ b/media/filters/manifest_demuxer_unittest.cc
@@ -235,4 +235,65 @@
   ASSERT_FALSE(manifest_demuxer_->has_next_task_for_testing());
 }
 
+TEST_F(ManifestDemuxerTest, CancelSeekAfterDemuxerBeforeEngine) {
+  // What happens if we seek, the demuxer replies, and while waiting for the
+  // engine to reply, we get a notice to cancel pending seek?
+
+  ManifestDemuxer::DelayCallback delay_cb;
+  EXPECT_CALL(*mock_engine_, OnTimeUpdate(_, _, _))
+      .WillRepeatedly([&delay_cb](base::TimeDelta, double,
+                                  ManifestDemuxer::DelayCallback cb) {
+        delay_cb = std::move(cb);
+      });
+
+  // a pending event is set, which won't be cleared until `delay_cb` is
+  // executed.
+  InitializeDemuxer();
+  ASSERT_TRUE(!!delay_cb);
+  ASSERT_FALSE(manifest_demuxer_->has_pending_seek_for_testing());
+  ASSERT_TRUE(manifest_demuxer_->has_pending_event_for_testing());
+
+  // Seek won't be called until we post delay_cb.
+  EXPECT_CALL(*mock_engine_, StartWaitingForSeek());
+  EXPECT_CALL(*mock_engine_, Seek(_)).Times(0);
+  EXPECT_CALL(*this, MockSeekComplete(_)).Times(0);
+  manifest_demuxer_->StartWaitingForSeek(base::Seconds(100));
+  manifest_demuxer_->Seek(base::Seconds(100),
+                          base::BindOnce(&ManifestDemuxerTest::MockSeekComplete,
+                                         base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+
+  // When we execute `delay_cb`, it will trigger `SeekInternal`, which will kick
+  // off a call to ChunkDemuxer::Seek and will also recapture a new `delay_cb`.
+  // The new `delay_cb` is bound to a task which completes the enigne seek step.
+  // The chunk demuxer should have already responded, and the pending seek
+  // should only be waiting on the engine.
+  EXPECT_CALL(*mock_engine_, Seek(_)).WillOnce(Return(true));
+  std::move(delay_cb).Run(kNoTimestamp);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(!!delay_cb);
+  ASSERT_TRUE(manifest_demuxer_->has_pending_seek_for_testing());
+  ASSERT_TRUE(manifest_demuxer_->has_pending_event_for_testing());
+
+  EXPECT_CALL(*mock_engine_, AbortPendingReads());
+  manifest_demuxer_->CancelPendingSeek(base::Seconds(5));
+  task_environment_.RunUntilIdle();
+  ASSERT_EQ(manifest_demuxer_->get_media_time_for_testing(), base::Seconds(5));
+
+  // Running `delay_cb` will finish the seek, and start a new update, even if
+  // it runs with kNoTimestamp.
+  EXPECT_CALL(*this, MockSeekComplete(_));
+  std::move(delay_cb).Run(kNoTimestamp);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(!!delay_cb);
+  ASSERT_EQ(manifest_demuxer_->get_media_time_for_testing(), base::Seconds(5));
+
+  // Run it again to end the loop.
+  std::move(delay_cb).Run(kNoTimestamp);
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(!delay_cb);
+  ASSERT_FALSE(manifest_demuxer_->has_pending_seek_for_testing());
+  ASSERT_FALSE(manifest_demuxer_->has_pending_event_for_testing());
+}
+
 }  // namespace media
diff --git a/net/BUILD.gn b/net/BUILD.gn
index b19c54b..ece7d87 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1267,6 +1267,7 @@
       "proxy_resolution/proxy_resolver_mac.cc",
       "proxy_resolution/proxy_resolver_mac.h",
     ]
+    configs += [ "//build/config/compiler:enable_arc" ]
   }
 
   if (is_win) {
@@ -3011,6 +3012,7 @@
 
   if (is_apple) {
     sources += [ "base/mac/url_conversions_unittest.mm" ]
+    configs += [ "//build/config/compiler:enable_arc" ]
   }
 
   if (is_mac) {
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index c772343a..a15bfc1 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -78,7 +78,6 @@
     ":embedded_test_server_aidl_java",
     ":net_java",
     "//base:base_java",
-    "//base:base_java_test_support",
     "//base:base_java_url_utils_for_test",
     "//base:jni_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -143,7 +142,9 @@
   # Used as an additional_apk in test scripts.
   never_incremental = true
 
-  enable_multidex = true
+  # Multidex requires a custom Application class to initialize it. Simpler to
+  # just disable it.
+  enable_multidex = false
 
   # Required on Android Q+ to read from /sdcard when installing certs.
   target_sdk_version = 28
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java
index c87df41c..a9e3dba1 100644
--- a/net/android/java/src/org/chromium/net/X509Util.java
+++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -163,11 +163,6 @@
     private static boolean sLoadedSystemKeyStore;
 
     /**
-     * A root that will installed as a user-trusted root for testing purposes.
-     */
-    private static X509Certificate sTestRoot;
-
-    /**
      * Lock object used to synchronize all calls that modify or depend on the trust managers.
      */
     private static final Object sLock = new Object();
@@ -324,31 +319,23 @@
                 new ByteArrayInputStream(derBytes));
     }
 
-    /**
-     * Add a test root certificate for use by the Android Platform verifier.
-     */
     public static void addTestRootCertificate(byte[] rootCertBytes)
             throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
         X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
         synchronized (sLock) {
             ensureTestInitializedLocked();
-            // Add the cert to be used by the Android Platform Verifier.
             sTestKeyStore.setCertificateEntry(
                     "root_cert_" + Integer.toString(sTestKeyStore.size()), rootCert);
             reloadTestTrustManager();
         }
     }
 
-    /**
-     * Clear test root certificates in use by the Android Platform verifier.
-     */
     public static void clearTestRootCertificates()
             throws NoSuchAlgorithmException, CertificateException, KeyStoreException {
         synchronized (sLock) {
             ensureTestInitializedLocked();
             try {
                 sTestKeyStore.load(null);
-                sTestRoot = null;
                 reloadTestTrustManager();
             } catch (IOException e) {
                 // No IO operation is attempted.
@@ -356,22 +343,6 @@
         }
     }
 
-    /**
-     * Set a test root certificate for use by the Chrome Cert verifier.
-     */
-    public static void setTestRootCertificateForBuiltin(byte[] rootCertBytes)
-            throws NoSuchAlgorithmException, CertificateException, KeyStoreException {
-        X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
-        synchronized (sLock) {
-            // Add the cert to be used by the Chrome Cert Verifier.
-            //
-            // This saves the root so it is returned from getUserAddedRoots, for TrustStoreAndroid.
-            // This is done for the Java EmbeddedTestServer implementation and must run before
-            // native code is loaded, when getUserAddedRoots is first run.
-            sTestRoot = rootCert;
-        }
-    }
-
     private static final char[] HEX_DIGITS = {
         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
         'a', 'b', 'c', 'd', 'e', 'f',
@@ -532,14 +503,6 @@
                 Log.e(TAG, "Error reading cert aliases: %s", e);
                 return new byte[0][];
             }
-
-            if (sTestRoot != null) {
-                try {
-                    userRootBytes.add(sTestRoot.getEncoded());
-                } catch (CertificateEncodingException e) {
-                    Log.e(TAG, "Error encoding test root cert, error %s", e);
-                }
-            }
         }
 
         return userRootBytes.toArray(new byte[0][]);
diff --git a/net/base/mac/url_conversions.mm b/net/base/mac/url_conversions.mm
index 88b15642..b3a27995 100644
--- a/net/base/mac/url_conversions.mm
+++ b/net/base/mac/url_conversions.mm
@@ -6,16 +6,20 @@
 
 #import <Foundation/Foundation.h>
 
-#include "base/mac/scoped_nsobject.h"
 #include "base/strings/escape.h"
 #include "url/gurl.h"
 #include "url/url_canon.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace net {
 
 NSURL* NSURLWithGURL(const GURL& url) {
-  if (!url.is_valid())
+  if (!url.is_valid()) {
     return nil;
+  }
 
   // NSURL strictly enforces RFC 1738 which requires that certain characters
   // are always encoded. These characters are: "<", ">", """, "#", "%", "{",
@@ -39,14 +43,15 @@
   }
   GURL escaped_url = url.ReplaceComponents(replacements);
 
-  base::scoped_nsobject<NSString> escaped_url_string(
-      [[NSString alloc] initWithUTF8String:escaped_url.spec().c_str()]);
+  NSString* escaped_url_string =
+      [NSString stringWithUTF8String:escaped_url.spec().c_str()];
   return [NSURL URLWithString:escaped_url_string];
 }
 
 GURL GURLWithNSURL(NSURL* url) {
-  if (url)
-    return GURL([[url absoluteString] UTF8String]);
+  if (url) {
+    return GURL(url.absoluteString.UTF8String);
+  }
   return GURL();
 }
 
diff --git a/net/base/mac/url_conversions_unittest.mm b/net/base/mac/url_conversions_unittest.mm
index 8390f4d..b6979ce 100644
--- a/net/base/mac/url_conversions_unittest.mm
+++ b/net/base/mac/url_conversions_unittest.mm
@@ -4,13 +4,16 @@
 
 #import <Foundation/Foundation.h>
 
-#include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #import "net/base/mac/url_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #include "url/gurl.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace net {
 
 namespace {
@@ -18,8 +21,8 @@
 class URLConversionTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    testData_.reset([[NSArray alloc]
-        initWithObjects:
+    test_data_ = [NSArray
+        arrayWithObjects:
             // Simple URL with protocol
             @"https://www.google.com/", @"https://www.google.com/",
 
@@ -201,30 +204,30 @@
             @"http://john!<]:bar[@foo.com/path",
             @"http://john!%3C%5D:bar%5B@foo.com/path",
 
-            nil]);
+            nil];
   }
 
   // NSArray of NSString pairs used for running the tests.
   // Each pair is in the form <input value, expected result>.
-  base::scoped_nsobject<NSArray> testData_;
+  NSArray<NSString*>* __strong test_data_;
 };
 
 TEST_F(URLConversionTest, TestNSURLCreationFromStrings) {
-  for (NSUInteger i = 0; i < [testData_ count]; i += 2) {
-    NSString* inputStr = [testData_ objectAtIndex:i];
-    NSString* expected = [testData_ objectAtIndex:(i + 1)];
-    NSURL* url = NSURLWithGURL(GURL(base::SysNSStringToUTF8(inputStr)));
-    EXPECT_NSEQ(expected, [url absoluteString]);
+  for (NSUInteger i = 0; i < test_data_.count; i += 2) {
+    NSString* input = test_data_[i];
+    NSString* expected = test_data_[i + 1];
+    NSURL* url = NSURLWithGURL(GURL(base::SysNSStringToUTF8(input)));
+    EXPECT_NSEQ(expected, url.absoluteString);
   }
 }
 
 TEST_F(URLConversionTest, TestURLWithStringDoesNotModifyAlreadyEscapedURLs) {
-  for (NSUInteger i = 0; i < [testData_ count]; i += 2) {
-    NSString* inputStr = [testData_ objectAtIndex:i + 1];
-    NSURL* url = NSURLWithGURL(GURL(base::SysNSStringToUTF8(inputStr)));
-    NSString* expected = [testData_ objectAtIndex:i + 1];
+  for (NSUInteger i = 0; i < test_data_.count; i += 2) {
+    NSString* input = test_data_[i + 1];
+    NSURL* url = NSURLWithGURL(GURL(base::SysNSStringToUTF8(input)));
+    NSString* expected = test_data_[i + 1];
     // Test the expected URL is created.
-    EXPECT_NSEQ(expected, [url absoluteString]);
+    EXPECT_NSEQ(expected, url.absoluteString);
   }
 }
 
diff --git a/net/base/net_string_util_icu_alternatives_ios.mm b/net/base/net_string_util_icu_alternatives_ios.mm
index 5fa3146..6726632 100644
--- a/net/base/net_string_util_icu_alternatives_ios.mm
+++ b/net/base/net_string_util_icu_alternatives_ios.mm
@@ -14,6 +14,10 @@
 #include "base/strings/sys_string_conversions.h"
 #include "net/base/net_string_util.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace net {
 
 namespace {
@@ -47,9 +51,10 @@
   base::ScopedCFTypeRef<CFStringRef> cfstring(CFStringCreateWithBytes(
       kCFAllocatorDefault, reinterpret_cast<const UInt8*>(text.data()),
       base::checked_cast<CFIndex>(text.length()), encoding,
-      false /* isExternalRepresentation */));
-  if (!cfstring)
+      /*isExternalRepresentation=*/false));
+  if (!cfstring) {
     return false;
+  }
   *output = base::SysCFStringRefToUTF8(cfstring.get());
   return true;
 }
@@ -76,10 +81,12 @@
 }
 
 bool ToUpper(base::StringPiece16 str, std::u16string* output) {
-  base::ScopedCFTypeRef<CFStringRef> cfstring(base::SysUTF16ToCFStringRef(str));
+  base::ScopedCFTypeRef<CFStringRef> cfstring =
+      base::SysUTF16ToCFStringRef(str);
   base::ScopedCFTypeRef<CFMutableStringRef> mutable_cfstring(
-      CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfstring.get()));
-  CFStringUppercase(mutable_cfstring.get(), nullptr);
+      CFStringCreateMutableCopy(kCFAllocatorDefault, /*maxLength=*/0,
+                                cfstring.get()));
+  CFStringUppercase(mutable_cfstring.get(), /*locale=*/nullptr);
   *output = base::SysCFStringRefToUTF16(mutable_cfstring.get());
   return true;
 }
diff --git a/net/base/network_change_notifier_mac.mm b/net/base/network_change_notifier_mac.mm
index cefb5ca..9166a97 100644
--- a/net/base/network_change_notifier_mac.mm
+++ b/net/base/network_change_notifier_mac.mm
@@ -20,6 +20,10 @@
 #import <CoreTelephony/CTTelephonyNetworkInfo.h>
 #endif
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 // The maximum number of seconds to wait for the connection type to be
 // determined.
@@ -117,11 +121,10 @@
     return CONNECTION_WIFI;
   }
   if (@available(iOS 12, *)) {
-    CTTelephonyNetworkInfo* info =
-        [[[CTTelephonyNetworkInfo alloc] init] autorelease];
+    CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
     NSDictionary<NSString*, NSString*>*
         service_current_radio_access_technology =
-            [info serviceCurrentRadioAccessTechnology];
+            info.serviceCurrentRadioAccessTechnology;
     NSSet<NSString*>* technologies_2g = [NSSet
         setWithObjects:CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyEdge,
                        CTRadioAccessTechnologyCDMA1x, nil];
@@ -279,7 +282,7 @@
 
   // Set the notification keys.  This starts us receiving notifications.
   bool ret = SCDynamicStoreSetNotificationKeys(store, notification_keys.get(),
-                                               nullptr);
+                                               /*patterns=*/nullptr);
   // TODO(willchan): Figure out a proper way to handle this rather than crash.
   CHECK(ret);
 #endif  // BUILDFLAG(IS_IOS)
diff --git a/net/base/platform_mime_util_mac.mm b/net/base/platform_mime_util_mac.mm
index 697fc6f..4c339d9 100644
--- a/net/base/platform_mime_util_mac.mm
+++ b/net/base/platform_mime_util_mac.mm
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "base/mac/bridging.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/notreached.h"
@@ -21,6 +22,10 @@
 #include <CoreServices/CoreServices.h>
 #endif  // BUILDFLAG(IS_IOS)
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace net {
 
 bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
@@ -39,7 +44,7 @@
     // Dynamic UTTypes are made by the system in the event that there's a
     // non-identifiable mime type. For now, we should treat dynamic UTTypes as a
     // nonstandard format.
-    if ([uttype isDynamic] || uttype.preferredMIMEType == nil) {
+    if (uttype.dynamic || uttype.preferredMIMEType == nil) {
       return false;
     }
     *result = base::SysNSStringToUTF8(uttype.preferredMIMEType);
@@ -56,7 +61,8 @@
     }
     base::ScopedCFTypeRef<CFStringRef> uti(
         UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
-                                              ext_ref, nullptr));
+                                              ext_ref,
+                                              /*inConformingToUTI=*/nullptr));
     if (!uti) {
       return false;
     }
@@ -85,7 +91,7 @@
   if (@available(macOS 11, iOS 14, *)) {
     UTType* uttype =
         [UTType typeWithMIMEType:base::SysUTF8ToNSString(mime_type)];
-    if ([uttype isDynamic] || uttype.preferredFilenameExtension == nil) {
+    if (uttype.dynamic || uttype.preferredFilenameExtension == nil) {
       return false;
     }
     *ext = base::SysNSStringToUTF8(uttype.preferredFilenameExtension);
@@ -102,7 +108,7 @@
     }
     base::ScopedCFTypeRef<CFStringRef> uti(
         UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime_ref,
-                                              nullptr));
+                                              /*inConformingToUTI=*/nullptr));
     if (!uti) {
       return false;
     }
@@ -180,7 +186,8 @@
             continue;
           }
           extensions_found = true;
-          for (NSString* extension in base::mac::CFToNSCast(extensions_list)) {
+          for (NSString* extension in base::mac::CFToNSPtrCast(
+                   extensions_list)) {
             extensions->insert(base::SysNSStringToUTF8(extension));
           }
         }
diff --git a/net/socket/connect_job_factory_unittest.cc b/net/socket/connect_job_factory_unittest.cc
index 45d59922..d3b0268 100644
--- a/net/socket/connect_job_factory_unittest.cc
+++ b/net/socket/connect_job_factory_unittest.cc
@@ -185,12 +185,11 @@
       /*websocket_endpoint_lock_manager=*/nullptr};
   TestConnectJobDelegate delegate_;
 
+  std::unique_ptr<ConnectJobFactory> factory_;
   raw_ptr<TestHttpProxyConnectJobFactory> http_proxy_job_factory_;
   raw_ptr<TestSocksConnectJobFactory> socks_job_factory_;
   raw_ptr<TestSslConnectJobFactory> ssl_job_factory_;
   raw_ptr<TestTransportConnectJobFactory> transport_job_factory_;
-
-  std::unique_ptr<ConnectJobFactory> factory_;
 };
 
 TEST_F(ConnectJobFactoryTest, CreateConnectJob) {
diff --git a/net/test/android/javatests/AndroidManifest.xml b/net/test/android/javatests/AndroidManifest.xml
index e3ad40b6..830392b 100644
--- a/net/test/android/javatests/AndroidManifest.xml
+++ b/net/test/android/javatests/AndroidManifest.xml
@@ -11,8 +11,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
 
-    <application android:label="ChromiumNetTestSupport"
-             android:name="androidx.multidex.MultiDexApplication">
+    <application android:label="ChromiumNetTestSupport">
 
         <uses-library android:name="android.test.runner" />
 
diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
index f5ce093..1b560e5 100644
--- a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
+++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
@@ -18,7 +18,6 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.UrlUtils;
 import org.chromium.net.X509Util;
 import org.chromium.net.test.util.CertTestUtil;
 
@@ -526,21 +525,4 @@
             throw new EmbeddedTestServerFailure("Failed to get root cert's path", e);
         }
     }
-
-    /**
-     * Initialize the test certs for the Certificate Verifiers.
-     */
-    public static void initTestCerts() {
-        try {
-            // Use the same PEM file as net/test/embedded_test_server/embedded_test_server.cc.
-            String rootCertPemPath =
-                    UrlUtils.getIsolatedTestFilePath("net/data/ssl/certificates/root_ca_cert.pem");
-            byte[] rootCertBytesDer = CertTestUtil.pemToDer(rootCertPemPath);
-            X509Util.addTestRootCertificate(rootCertBytesDer);
-            X509Util.setTestRootCertificateForBuiltin(rootCertBytesDer);
-        } catch (Exception e) {
-            throw new EmbeddedTestServer.EmbeddedTestServerFailure(
-                    "Failed to install root certificate.", e);
-        }
-    }
 }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 46dd193..38873cfb 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -3471,8 +3471,7 @@
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
           "--avd-config=../../tools/android/avd/proto/generic_android30.textpb",
-          "--git-revision=${got_revision}",
-          "--avd-config=../../tools/android/avd/proto/generic_playstore_android30.textpb"
+          "--git-revision=${got_revision}"
         ],
         "merge": {
           "args": [
@@ -3507,14 +3506,14 @@
           ],
           "named_caches": [
             {
-              "name": "generic_playstore_android30",
-              "path": ".android_emulator/generic_playstore_android30"
+              "name": "generic_android30",
+              "path": ".android_emulator/generic_android30"
             }
           ],
           "optional_dimensions": {
             "60": [
               {
-                "caches": "generic_playstore_android30"
+                "caches": "generic_android30"
               }
             ]
           },
@@ -7643,6 +7642,75 @@
       },
       {
         "args": [
+          "--gtest_filter=org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerTest.test*ExternalNavigationWithUserGesture*:org.chromium.shape_detection.*",
+          "--use-persistent-shell",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android31.textpb",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_test_apk_with_playstore"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "chrome_public_test_apk_with_playstore",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cores": "8",
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "os": "Ubuntu-22.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "generic_android31",
+              "path": ".android_emulator/generic_android31"
+            }
+          ],
+          "optional_dimensions": {
+            "60": [
+              {
+                "caches": "generic_android31"
+              }
+            ]
+          },
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "chrome_public_test_apk",
+        "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
+      },
+      {
+        "args": [
           "--use-persistent-shell",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -30699,7 +30767,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "os": "Ubuntu-18.04",
+              "os": "Ubuntu-22.04",
               "pool": "chromium.tests.avd"
             }
           ],
@@ -34229,6 +34297,73 @@
       },
       {
         "args": [
+          "--gtest_filter=org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerTest.test*ExternalNavigationWithUserGesture*:org.chromium.shape_detection.*",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--git-revision=${got_revision}"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_test_apk_with_playstore"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "chrome_public_test_apk_with_playstore",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cores": "4",
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "os": "Ubuntu-18.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "generic_android28",
+              "path": ".android_emulator/generic_android28"
+            }
+          ],
+          "optional_dimensions": {
+            "60": [
+              {
+                "caches": "generic_android28"
+              }
+            ]
+          },
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "chrome_public_test_apk",
+        "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
+      },
+      {
+        "args": [
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
           "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index a1ee335..e88cce30 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5734,9 +5734,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5747,8 +5747,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -5899,9 +5899,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5912,8 +5912,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -6046,9 +6046,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6059,8 +6059,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 39a40285..3999927d 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -7714,7 +7714,7 @@
               "cpu": "x86-64",
               "device_os": null,
               "device_type": null,
-              "os": "Ubuntu-18.04",
+              "os": "Ubuntu-22.04",
               "pool": "chromium.tests.avd"
             }
           ],
@@ -25539,9 +25539,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25552,8 +25552,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -25704,9 +25704,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25717,8 +25717,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -25851,9 +25851,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25864,8 +25864,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json
index fe7d2d8a..5bc5b23a 100644
--- a/testing/buildbot/chromium.dawn.json
+++ b/testing/buildbot/chromium.dawn.json
@@ -3363,7 +3363,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3390,7 +3390,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3417,7 +3417,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3444,7 +3444,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3470,7 +3470,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3494,7 +3494,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3526,7 +3526,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3550,7 +3550,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3590,7 +3590,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3629,7 +3629,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3666,7 +3666,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3706,7 +3706,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3746,7 +3746,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3785,7 +3785,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3824,7 +3824,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -3866,7 +3866,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9beee7b..9c9a78b 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -40637,6 +40637,72 @@
       }
     ]
   },
+  "linux-cr23-rel": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "interactive_ui_tests",
+        "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "views_unittests",
+        "test_id_prefix": "ninja://ui/views:views_unittests/"
+      }
+    ]
+  },
   "linux-fieldtrial-rel": {
     "gtest_tests": [
       {
@@ -41528,9 +41594,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -41540,8 +41606,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -41693,9 +41759,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -41705,8 +41771,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -41840,9 +41906,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -41852,8 +41918,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -43317,9 +43383,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43329,8 +43395,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -43482,9 +43548,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43494,8 +43560,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -43629,9 +43695,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43641,8 +43707,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -44377,9 +44443,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44389,8 +44455,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -47520,6 +47586,72 @@
       }
     ]
   },
+  "mac-cr23-rel": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-12"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-12"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "interactive_ui_tests",
+        "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Mac-12"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "views_unittests",
+        "test_id_prefix": "ninja://ui/views:views_unittests/"
+      }
+    ]
+  },
   "mac-fieldtrial-tester": {
     "gtest_tests": [
       {
@@ -50255,6 +50387,72 @@
       }
     ]
   },
+  "win-cr23-rel": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "interactive_ui_tests",
+        "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/"
+      },
+      {
+        "args": [
+          "--enable-features=ChromeRefresh2023"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Windows-10"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "views_unittests",
+        "test_id_prefix": "ninja://ui/views:views_unittests/"
+      }
+    ]
+  },
   "win-fieldtrial-rel": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index df58fcfb..1d9e72d 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -9597,10 +9597,221 @@
     ]
   },
   "Mac FYI Experimental Release (Apple M1)": {
+    "gtest_tests": [
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "angle_unittests",
+        "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/",
+        "use_isolated_scripts_api": true
+      },
+      {
+        "args": [
+          "--enable-gpu",
+          "--test-launcher-bot-mode",
+          "--test-launcher-jobs=1",
+          "--gtest_filter=TabCaptureApiPixelTest.EndToEnd*"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "tab_capture_end2end_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "browser_tests",
+        "test_id_prefix": "ninja://chrome/test:browser_tests/"
+      },
+      {
+        "args": [
+          "--use-cmd-decoder=passthrough",
+          "--use-gl=angle",
+          "--use-gpu-in-tests"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "gl_tests_passthrough",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test": "gl_tests",
+        "test_id_prefix": "ninja://gpu:gl_tests/"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "gl_unittests",
+        "test_id_prefix": "ninja://ui/gl:gl_unittests/"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "gles2_conform_test",
+        "test_id_prefix": "ninja://gpu/gles2_conform_support:gles2_conform_test/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "gpu_unittests",
+        "test_id_prefix": "ninja://gpu:gpu_unittests/"
+      },
+      {
+        "args": [
+          "--gtest_filter=*Detection*",
+          "--use-gpu-in-tests"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "services_unittests",
+        "test_id_prefix": "ninja://services:services_unittests/"
+      }
+    ],
     "isolated_scripts": [
       {
         "args": [
-          "noop_sleep",
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "context_lost_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "gpu_process",
           "--show-stdout",
           "--browser=release",
           "--passthrough",
@@ -9612,7 +9823,11 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "noop_sleep_tests",
+        "name": "gpu_process_launch_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
         "should_retry_with_patch": false,
         "swarming": {
           "can_use_on_swarming_builders": true,
@@ -9622,7 +9837,527 @@
               "cpu": "arm64",
               "display_attached": "1",
               "mac_model": "Macmini9,1",
-              "os": "Mac-12.5.1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "hardware_accelerated_feature_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "info_collection",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--expected-vendor-id",
+          "106b",
+          "--expected-device-id",
+          "0"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "info_collection_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "maps_pixel_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "mediapipe",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=passthrough --use-gl=angle"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "mediapipe_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "pixel_skia_gold_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
+          "--dont-restore-color-profile-after-test"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "screenshot_sync_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "trace_test",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webcodecs",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webcodecs_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgl2_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json",
+          "--jobs=4"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl2_conformance_gl_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 20
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgl2_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=metal --use-cmd-decoder=passthrough --enable-features=EGLDualGPURendering,ForceHighPerformanceGPUForWebGL",
+          "--webgl-conformance-version=2.0.1",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json",
+          "--jobs=4"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl2_conformance_metal_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 20
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgl1_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json",
+          "--jobs=4"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl_conformance_gl_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgl1_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=metal --use-cmd-decoder=passthrough --enable-features=EGLDualGPURendering,ForceHighPerformanceGPUForWebGL",
+          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json",
+          "--jobs=4"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl_conformance_metal_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
+              "pool": "chromium.tests"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgl1_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=swiftshader --use-cmd-decoder=passthrough --force_high_performance_gpu",
+          "--test-filter=conformance/rendering/gl-drawelements.html",
+          "--jobs=4"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgl_conformance_swangle_passthrough_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "display_attached": "1",
+              "mac_model": "Macmini9,1",
+              "os": "Mac-13.2",
               "pool": "chromium.tests"
             }
           ],
@@ -9647,7 +10382,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9676,7 +10411,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9703,7 +10438,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9728,7 +10463,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9752,7 +10487,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9773,7 +10508,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9798,7 +10533,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9837,7 +10572,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9874,7 +10609,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9911,7 +10646,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9952,7 +10687,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -9998,7 +10733,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10035,7 +10770,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10081,7 +10816,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10119,7 +10854,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10156,7 +10891,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10193,7 +10928,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10233,7 +10968,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10274,7 +11009,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10314,7 +11049,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10354,7 +11089,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
@@ -10394,7 +11129,7 @@
               "cpu": "x86-64",
               "display_attached": "1",
               "gpu": "8086:3e9b",
-              "os": "Mac-13.2"
+              "os": "Mac-13.3.1"
             }
           ],
           "expiration": 21600,
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 56e6bad01..02ea862 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18116,12 +18116,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18132,8 +18132,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -18301,12 +18301,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18317,8 +18317,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
@@ -18463,12 +18463,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 115.0.5752.0",
+        "description": "Run with ash-chrome version 115.0.5753.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18479,8 +18479,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v115.0.5752.0",
-              "revision": "version:115.0.5752.0"
+              "location": "lacros_version_skew_tests_v115.0.5753.0",
+              "revision": "version:115.0.5753.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
index 76a0296..c92427d 100644
--- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
+++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
@@ -75,7 +75,6 @@
 -EncryptionMigrationTest.*
 -EnrollmentLocalPolicyServerBase.*
 -EnrollmentRecoveryTest.*
--EnrollmentScreenChromadMigrationTest.*
 -EnrollmentScreenHandsOffTest.*
 -EnrollmentScreenTest.*
 -EnterpriseEnrollmentTest.*
@@ -176,7 +175,6 @@
 -WebviewLoginTest.*
 -WebviewProxyAuthLoginTest.*
 -WelcomeScreenBrowserTest.*
--WelcomeScreenChromadMigrationBrowserTest.*
 -WelcomeScreenChromeVoxHintTest.*
 -WelcomeScreenHandsOffBrowserTest.*
 -WelcomeScreenInternationalChromeVoxHintTest.*
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
index a4d862c..3d4bf339 100644
--- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
+++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
@@ -75,7 +75,6 @@
 EncryptionMigrationTest.*
 EnrollmentLocalPolicyServerBase.*
 EnrollmentRecoveryTest.*
-EnrollmentScreenChromadMigrationTest.*
 EnrollmentScreenHandsOffTest.*
 EnrollmentScreenTest.*
 EnterpriseEnrollmentTest.*
@@ -176,7 +175,6 @@
 WebviewLoginTest.*
 WebviewProxyAuthLoginTest.*
 WelcomeScreenBrowserTest.*
-WelcomeScreenChromadMigrationBrowserTest.*
 WelcomeScreenChromeVoxHintTest.*
 WelcomeScreenHandsOffBrowserTest.*
 WelcomeScreenInternationalChromeVoxHintTest.*
diff --git a/testing/buildbot/filters/pixel_tests.filter b/testing/buildbot/filters/pixel_tests.filter
index 33d6621..fb63e9b 100644
--- a/testing/buildbot/filters/pixel_tests.filter
+++ b/testing/buildbot/filters/pixel_tests.filter
@@ -34,7 +34,7 @@
 FirstRunIntroPixelTest.*
 GlobalErrorBubbleTest.*
 HatsBubbleTest.*
-HighEfficiencyFaviconTreatmentTest.*
+*HighEfficiencyFaviconTreatmentTest.*
 HomeButtonUiTest.*
 HungRendererDialogViewBrowserTest.*
 ImportLockDialogViewBrowserTest.*
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index f91124d..a9a4b70 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -887,7 +887,7 @@
       'dimensions': {
         'cpu': 'arm64',
         'mac_model': 'Macmini9,1',
-        'os': 'Mac-12.5.1',
+        'os': 'Mac-13.2',
         'pool': 'chromium.tests',
         'display_attached': '1',
       },
@@ -925,7 +925,7 @@
       'dimensions': {
         'cpu': 'x86-64',
         'gpu': '8086:3e9b',
-        'os': 'Mac-13.2',
+        'os': 'Mac-13.3.1',
         'display_attached': '1',
       },
     },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 86bdefc..549ecf8 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1495,57 +1495,6 @@
       },
     },
   },
-  'chrome_public_test_apk_with_playstore': {
-    # TODO(crbug.com/1442470): This test suite fails on these builders.
-    'remove_from': [
-      'android-12-x64-rel',
-      'android-pie-x86-rel',
-    ],
-    'modifications': {
-      'android-11-x86-rel': {
-        'args': [
-          '--avd-config=../../tools/android/avd/proto/generic_playstore_android30.textpb',
-        ],
-        'swarming': {
-          # soft affinity so that bots with caches will be picked first
-          'optional_dimensions': {
-            '60': [
-              {
-                'caches': 'generic_playstore_android30',
-              }
-            ],
-          },
-          'named_caches': [
-            {
-              'name': 'generic_playstore_android30',
-              'path': '.android_emulator/generic_playstore_android30',
-            },
-          ],
-        },
-      },
-      'android-pie-x86-rel': {
-        'args': [
-          '--avd-config=../../tools/android/avd/proto/generic_playstore_android28.textpb',
-        ],
-        'swarming': {
-          # soft affinity so that bots with caches will be picked first
-          'optional_dimensions': {
-            '60': [
-              {
-                'caches': 'generic_playstore_android28',
-              }
-            ],
-          },
-          'named_caches': [
-            {
-              'name': 'generic_playstore_android28',
-              'path': '.android_emulator/generic_playstore_android28',
-            },
-          ],
-        },
-      },
-    },
-  },
   'chrome_public_test_vr_apk': {
     'remove_from': [
       'android-pie-arm64-rel', # https://crbug.com/1010211
@@ -4555,6 +4504,12 @@
           '--use-persistent-shell',
         ],
         'swarming': {
+          'dimension_sets': [
+            {
+              # TODO(crbug.com/1412588): Move the remainder to Jammy.
+              'os': 'Ubuntu-22.04',
+            },
+          ],
           'shards': 27,
         },
       },
@@ -4581,6 +4536,12 @@
           '--use-persistent-shell',
         ],
         'swarming': {
+          'dimension_sets': [
+            {
+              # TODO(crbug.com/1412588): Move the remainder to Jammy.
+              'os': 'Ubuntu-22.04',
+            },
+          ],
           'shards': 27,
         },
       },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index e866176..11d72d9 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -1759,6 +1759,30 @@
       },
     },
 
+    'cr23_gtests': {
+      'browser_tests': {
+        'args': [
+          '--enable-features=ChromeRefresh2023',
+        ],
+        'swarming': {
+          'shards': 10,
+        },
+      },
+      'interactive_ui_tests': {
+        'args': [
+          '--enable-features=ChromeRefresh2023',
+        ],
+        'swarming': {
+          'shards': 10,
+        },
+      },
+      'views_unittests': {
+        'args': [
+          '--enable-features=ChromeRefresh2023',
+        ],
+      },
+    },
+
     'cronet_gtests': {
       'cronet_sample_test_apk': {},
       'cronet_smoketests_missing_native_library_instrumentation_apk': {},
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 1d63370..b3de9f63d 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5752.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5753.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 115.0.5752.0',
+    'description': 'Run with ash-chrome version 115.0.5753.0',
     'identifier': 'Lacros version skew testing ash canary',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v115.0.5752.0',
-          'revision': 'version:115.0.5752.0',
+          'location': 'lacros_version_skew_tests_v115.0.5753.0',
+          'revision': 'version:115.0.5753.0',
         },
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 964f8ce..d83caa1 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -3545,6 +3545,16 @@
           'scripts': 'test_traffic_annotation_auditor_script'
         },
       },
+      'linux-cr23-rel': {
+        'mixins': [
+          'linux-bionic',
+          'x86-64',
+        ],
+        'test_suites': {
+          'gtest_tests': 'cr23_gtests'
+        },
+        'os_type': 'linux',
+      },
       'linux-fieldtrial-rel': {
         'mixins': [
           'linux-bionic',
@@ -3718,6 +3728,15 @@
           '--enable-features=PartitionAllocBackupRefPtr:enabled-processes/non-renderer',
         ],
       },
+      'mac-cr23-rel': {
+        'test_suites': {
+          'gtest_tests': 'cr23_gtests',
+        },
+        'mixins': [
+          'mac_x64',
+        ],
+        'os_type': 'mac',
+      },
       'mac-fieldtrial-tester': {
         'mixins': [
           'finch-chromium-swarming-pool',
@@ -3848,6 +3867,16 @@
           '--enable-features=PartitionAllocBackupRefPtr:enabled-processes/non-renderer',
         ],
       },
+      'win-cr23-rel': {
+        'test_suites': {
+          'gtest_tests': 'cr23_gtests',
+        },
+        'mixins': [
+          'win10-any',
+          'x86-64',
+        ],
+        'os_type': 'win',
+      },
       'win-fieldtrial-rel': {
         'mixins': [
             'win10',
@@ -4631,7 +4660,8 @@
         # the gpu_noop_sleep_telemetry_test test should be used. Otherwise, this
         # should have the same test_suites as 'Mac FYI Release (Apple M1)'.
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_noop_sleep_telemetry_test',
+          'gtest_tests': 'gpu_fyi_mac_release_gtests',
+          'gpu_telemetry_tests': 'gpu_fyi_mac_release_telemetry_tests',
         },
       },
       'Mac FYI Experimental Release (Intel)': {
diff --git a/testing/merge_scripts/code_coverage/convert_to_istanbul.js b/testing/merge_scripts/code_coverage/convert_to_istanbul.js
index bdcfea0..b58628fa 100644
--- a/testing/merge_scripts/code_coverage/convert_to_istanbul.js
+++ b/testing/merge_scripts/code_coverage/convert_to_istanbul.js
@@ -40,13 +40,17 @@
   let result = consumer.originalPositionFor({line: 1, column: 0});
 
   let file = null
-  try {
-    file = await readFile(result.source, 'utf8');
-  } catch(error) {
-    if (error.code === 'ENOENT') {
-      exists = false
-    } else {
-      throw error;
+  if (!result || !result.source) {
+    exists = false
+  } else {
+    try {
+      file = await readFile(result.source, 'utf8');
+    } catch(error) {
+      if (error.code === 'ENOENT') {
+        exists = false
+      } else {
+        throw error;
+      }
     }
   }
 
diff --git a/testing/merge_scripts/code_coverage/merge_js_lib.py b/testing/merge_scripts/code_coverage/merge_js_lib.py
index 13fd4626..91d441c 100644
--- a/testing/merge_scripts/code_coverage/merge_js_lib.py
+++ b/testing/merge_scripts/code_coverage/merge_js_lib.py
@@ -279,7 +279,7 @@
   Raises:
     RuntimeError: If the underlying node command fails.
   """
-    return node.RunNode([
+    stdout = node.RunNode([
         os.path.join(_HERE_PATH, 'convert_to_istanbul.js'),
         '--source-dir',
         source_dir,
@@ -288,6 +288,7 @@
         '--raw-coverage-dirs',
         *raw_coverage_dirs,
     ])
+    logging.info(stdout)
 
 
 def merge_istanbul_reports(istanbul_coverage_dir, source_dir, output_file):
diff --git a/testing/merge_scripts/code_coverage/merge_js_results.py b/testing/merge_scripts/code_coverage/merge_js_results.py
index 2e9a6d8..29003e5 100755
--- a/testing/merge_scripts/code_coverage/merge_js_results.py
+++ b/testing/merge_scripts/code_coverage/merge_js_results.py
@@ -60,7 +60,7 @@
         istanbul_coverage_dir = os.path.join(params.task_output_dir,
                                              'istanbul')
         output_dir = os.path.join(istanbul_coverage_dir, 'merged')
-        os.makedirs(output_dir)
+        os.makedirs(output_dir, exist_ok=True)
 
         coverage_file_path = os.path.join(output_dir, 'coverage.json')
         logging.info('Merging istanbul reports to %s', coverage_file_path)
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f98ba679..2cbb6409 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2473,21 +2473,6 @@
             ]
         }
     ],
-    "CertVerifierBuiltin": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "ChromeRootStoreUsed"
-                    ]
-                }
-            ]
-        }
-    ],
     "ChangeExtensionEventPageSuspendDelay": [
         {
             "platforms": [
@@ -4337,6 +4322,27 @@
             ]
         }
     ],
+    "DisableCanvasOverdrawOptimization": [
+        {
+            "platforms": [
+                "fuchsia",
+                "linux",
+                "mac",
+                "windows",
+                "chromeos",
+                "chromeos_lacros",
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "DisableCanvasOverdrawOptimization"
+                    ]
+                }
+            ]
+        }
+    ],
     "DisableGles2ForOopR": [
         {
             "platforms": [
@@ -6200,6 +6206,28 @@
             ]
         }
     ],
+    "HappinessTrackingSystemBatteryLife": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "histogram_name": "ChromeOS.HaTS.BatteryLife",
+                        "prob": "0.02",
+                        "survey_cycle_length": "7",
+                        "survey_start_date_ms": "1681974000000",
+                        "trigger_id": "1xncr1Dp20jBnuKU19R0XpozVULu"
+                    },
+                    "enable_features": [
+                        "HappinessTrackingSystemBatteryLife"
+                    ]
+                }
+            ]
+        }
+    ],
     "HappinessTrackingSystemPerformance": [
         {
             "platforms": [
@@ -10180,25 +10208,6 @@
             ]
         }
     ],
-    "PreloadingDesktopSettingsSubPage": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PreloadingDesktopSettingsSubPage"
-                    ]
-                }
-            ]
-        }
-    ],
     "Prerender2DUIConfidenceCutoff": [
         {
             "platforms": [
@@ -10252,29 +10261,6 @@
             ]
         }
     ],
-    "PrewarmLookalikeCheck": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_TwoRedirects",
-                    "params": {
-                        "redirect_lookup_cache_limit": "2"
-                    },
-                    "enable_features": [
-                        "PrewarmLookalikeCheck"
-                    ]
-                }
-            ]
-        }
-    ],
     "PriceDropNtpIPH": [
         {
             "platforms": [
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index f412694..1a76116 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -4449,14 +4449,48 @@
   return &shadow_root;
 }
 
+bool Element::AttachStreamingDeclarativeShadowRoot(
+    HTMLTemplateElement& template_element,
+    ShadowRootType type,
+    FocusDelegation focus_delegation,
+    SlotAssignmentMode slot_assignment) {
+  CHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed);
+  CHECK(!template_element.IsNonStreamingDeclarativeShadowRoot());
+
+  // 12. Run attach a shadow root with shadow host equal to declarative shadow
+  // host element, mode equal to declarative shadow mode, and delegates focus
+  // equal to declarative shadow delegates focus. If an exception was thrown by
+  // attach a shadow root, catch it, and ignore the exception.
+  if (const char* error_message = ErrorMessageForAttachShadow()) {
+    template_element.SetDeclarativeShadowRootType(
+        DeclarativeShadowRootType::kNone);
+    GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+        mojom::blink::ConsoleMessageSource::kOther,
+        mojom::blink::ConsoleMessageLevel::kError, error_message));
+    return false;
+  }
+
+  ShadowRoot& shadow_root =
+      AttachShadowRootInternal(type, focus_delegation, slot_assignment);
+  // 13.1. Set declarative shadow host element's shadow host's "is declarative
+  // shadow root" property to true.
+  shadow_root.SetIsDeclarativeShadowRoot(true);
+  // 13.NEW. Set declarative shadow host element's shadow host's "available
+  // to element internals" to true.
+  shadow_root.SetAvailableToElementInternals(true);
+  return true;
+}
+
 // TODO(crbug.com/1396384) Remove this entire function when the older version
 // of declarative shadow DOM is removed.
-bool Element::AttachDeclarativeShadowRoot(HTMLTemplateElement* template_element,
-                                          ShadowRootType type,
-                                          FocusDelegation focus_delegation,
-                                          SlotAssignmentMode slot_assignment) {
-  DCHECK(template_element);
-  DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed);
+bool Element::AttachDeprecatedNonStreamingDeclarativeShadowRoot(
+    HTMLTemplateElement& template_element,
+    ShadowRootType type,
+    FocusDelegation focus_delegation,
+    SlotAssignmentMode slot_assignment) {
+  CHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed);
+  CHECK(template_element.IsNonStreamingDeclarativeShadowRoot());
+
   Deprecation::CountDeprecation(
       GetDocument().GetExecutionContext(),
       mojom::blink::WebFeature::kDeclarativeShadowRoot);
@@ -4466,7 +4500,7 @@
   // equal to declarative shadow delegates focus. If an exception was thrown by
   // attach a shadow root, catch it, and ignore the exception.
   if (const char* error_message = ErrorMessageForAttachShadow()) {
-    template_element->SetDeclarativeShadowRootType(
+    template_element.SetDeclarativeShadowRootType(
         DeclarativeShadowRootType::kNone);
     GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
         mojom::blink::ConsoleMessageSource::kOther,
@@ -4483,15 +4517,13 @@
   // to element internals" to true.
   shadow_root.SetAvailableToElementInternals(true);
 
-  if (template_element->IsNonStreamingDeclarativeShadowRoot()) {
-    // 13.2. Append the declarative template element's DocumentFragment to the
-    // newly-created shadow root.
-    shadow_root.ParserTakeAllChildrenFrom(
-        *template_element->DeclarativeShadowContent());
-    // 13.3. Remove the declarative template element from the document.
-    if (template_element->parentNode()) {
-      template_element->parentNode()->ParserRemoveChild(*template_element);
-    }
+  // 13.2. Append the declarative template element's DocumentFragment to the
+  // newly-created shadow root.
+  shadow_root.ParserTakeAllChildrenFrom(
+      *template_element.DeclarativeShadowContent());
+  // 13.3. Remove the declarative template element from the document.
+  if (template_element.parentNode()) {
+    template_element.parentNode()->ParserRemoveChild(template_element);
   }
   return true;
 }
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 3085364..b7d9f94 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -662,10 +662,16 @@
   ShadowRoot* attachShadow(const ShadowRootInit*, ExceptionState&);
 
   // Returns true if the attachment was successful.
-  bool AttachDeclarativeShadowRoot(HTMLTemplateElement*,
-                                   ShadowRootType,
-                                   FocusDelegation,
-                                   SlotAssignmentMode);
+  bool AttachStreamingDeclarativeShadowRoot(HTMLTemplateElement&,
+                                            ShadowRootType,
+                                            FocusDelegation,
+                                            SlotAssignmentMode);
+  // TODO(crbug.com/1396384) Remove this entire function when the older version
+  // of declarative shadow DOM is removed.
+  bool AttachDeprecatedNonStreamingDeclarativeShadowRoot(HTMLTemplateElement&,
+                                                         ShadowRootType,
+                                                         FocusDelegation,
+                                                         SlotAssignmentMode);
 
   ShadowRoot& CreateUserAgentShadowRoot();
   ShadowRoot& AttachShadowRootInternal(
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 177f389..f1145da 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2053,7 +2053,7 @@
         !resize_controller->IsLoopLimitErrorDispatched()) {
       resize_controller->ClearObservations();
       ErrorEvent* error = ErrorEvent::Create(
-          "ResizeObserver loop limit exceeded",
+          "ResizeObserver loop completed with undelivered notifications.",
           CaptureSourceLocation(frame_->DomWindow()), nullptr);
       // We're using |SanitizeScriptErrors::kDoNotSanitize| as the error is made
       // by blink itself.
diff --git a/third_party/blink/renderer/core/html/html_details_element.cc b/third_party/blink/renderer/core/html/html_details_element.cc
index 4e96b0c9..cd901d8 100644
--- a/third_party/blink/renderer/core/html/html_details_element.cc
+++ b/third_party/blink/renderer/core/html/html_details_element.cc
@@ -45,19 +45,6 @@
 
 namespace blink {
 
-namespace {
-
-bool IsFirstSummary(const Node& node) {
-  DCHECK(IsA<HTMLDetailsElement>(node.parentElement()));
-  if (!IsA<HTMLSummaryElement>(node))
-    return false;
-  return node.parentElement() &&
-         &node ==
-             Traversal<HTMLSummaryElement>::FirstChild(*node.parentElement());
-}
-
-}  // namespace
-
 HTMLDetailsElement::HTMLDetailsElement(Document& document)
     : HTMLElement(html_names::kDetailsTag, document), is_open_(false) {
   UseCounter::Count(document, WebFeature::kDetailsElement);
@@ -144,9 +131,13 @@
   HeapVector<Member<Node>> summary_nodes;
   HeapVector<Member<Node>> content_nodes;
   for (Node& child : NodeTraversal::ChildrenOf(*this)) {
-    if (!child.IsSlotable())
+    if (!child.IsSlotable()) {
+      CHECK(!IsA<HTMLSummaryElement>(child));
       continue;
-    if (IsFirstSummary(child)) {
+    }
+    bool is_first_summary =
+        summary_nodes.empty() && IsA<HTMLSummaryElement>(child);
+    if (is_first_summary) {
       summary_nodes.push_back(child);
     } else {
       content_nodes.push_back(child);
diff --git a/third_party/blink/renderer/core/html/html_template_element.h b/third_party/blink/renderer/core/html/html_template_element.h
index 0e5ac65..1a399eab 100644
--- a/third_party/blink/renderer/core/html/html_template_element.h
+++ b/third_party/blink/renderer/core/html/html_template_element.h
@@ -114,6 +114,8 @@
   DeclarativeShadowRootType declarative_shadow_root_type_;
 };
 
+// TODO(crbug.com/1396384) Remove this entire function when the older version
+// of declarative shadow DOM is removed.
 ALWAYS_INLINE bool HTMLTemplateElement::IsNonStreamingDeclarativeShadowRoot()
     const {
   switch (declarative_shadow_root_type_) {
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
index c06c397a..c8c11a08 100644
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.cc
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
@@ -833,12 +833,13 @@
     auto slot_assignment_mode = SlotAssignmentMode::kNamed;
     HTMLStackItem* shadow_host_stack_item = open_elements_.TopStackItem();
     Element* host = shadow_host_stack_item->GetElement();
+
     ShadowRootType type = declarative_shadow_root_type ==
                                   DeclarativeShadowRootType::kStreamingOpen
                               ? ShadowRootType::kOpen
                               : ShadowRootType::kClosed;
-    bool success = host->AttachDeclarativeShadowRoot(
-        template_element, type, focus_delegation, slot_assignment_mode);
+    bool success = host->AttachStreamingDeclarativeShadowRoot(
+        *template_element, type, focus_delegation, slot_assignment_mode);
     if (success) {
       DCHECK(host->AuthorShadowRoot());
       UseCounter::Count(host->GetDocument(),
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
index 8a8a70f..7266d14 100644
--- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
+++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -1085,13 +1085,14 @@
           // TODO(crbug.com/1063157): Add an attribute for imperative slot
           // assignment.
           auto slot_assignment_mode = SlotAssignmentMode::kNamed;
-          shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot(
-              template_element,
-              template_element->GetDeclarativeShadowRootType() ==
-                      DeclarativeShadowRootType::kOpen
-                  ? ShadowRootType::kOpen
-                  : ShadowRootType::kClosed,
-              focus_delegation, slot_assignment_mode);
+          shadow_host_stack_item->GetElement()
+              ->AttachDeprecatedNonStreamingDeclarativeShadowRoot(
+                  *template_element,
+                  template_element->GetDeclarativeShadowRootType() ==
+                          DeclarativeShadowRootType::kOpen
+                      ? ShadowRootType::kOpen
+                      : ShadowRootType::kClosed,
+                  focus_delegation, slot_assignment_mode);
         }
       }
     }
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
index af5ab889..8b1ca01 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -1687,35 +1687,15 @@
     InitAndCacheTrackSizes(kForRows);
   }
 
-  if (subtree_size == 1) {
-    // If we know this subtree doesn't have nested subgrids we can exit early
-    // instead of iterating over every grid item looking for them.
-    return;
-  }
-
-  auto next_subgrid_subtree = sizing_subtree.FirstChild();
-  for (const auto& grid_item : grid_items) {
-    if (grid_item.is_subgridded_to_parent_grid || !grid_item.IsSubgrid()) {
-      continue;
-    }
-
-    DCHECK(next_subgrid_subtree);
-    NGSubgriddedItemData subgrid_data(grid_item, layout_data);
-
-    const auto space = CreateConstraintSpaceForSubgridAlgorithm(subgrid_data);
-    const auto fragment_geometry = CalculateInitialFragmentGeometry(
-        space, subgrid_data->node, /* break_token */ nullptr,
-        /* is_intrinsic */ HasIndefiniteInlineSize(space));
-
-    const NGGridLayoutAlgorithm subgrid_algorithm(
-        {subgrid_data->node, fragment_geometry, space});
-
-    subgrid_algorithm.InitializeTrackSizes(
-        next_subgrid_subtree, subgrid_data,
-        RelativeDirectionFilterInSubgrid(opt_track_direction, grid_item));
-
-    next_subgrid_subtree = next_subgrid_subtree.NextSibling();
-  }
+  ForEachSubgrid(sizing_subtree,
+                 [&](const NGGridLayoutAlgorithm& subgrid_algorithm,
+                     const NGGridSizingSubtree& subgrid_subtree,
+                     const NGSubgriddedItemData& subgrid_data) {
+                   subgrid_algorithm.InitializeTrackSizes(
+                       subgrid_subtree, subgrid_data,
+                       RelativeDirectionFilterInSubgrid(opt_track_direction,
+                                                        *subgrid_data));
+                 });
 }
 
 void NGGridLayoutAlgorithm::InitializeTrackSizes(
@@ -1878,9 +1858,38 @@
     }
   }
 
+  ForEachSubgrid(
+      sizing_subtree, [&](const NGGridLayoutAlgorithm& subgrid_algorithm,
+                          const NGGridSizingSubtree& subgrid_subtree,
+                          const NGSubgriddedItemData& subgrid_data) {
+        subgrid_algorithm.CompleteTrackSizingAlgorithm(
+            subgrid_subtree, subgrid_data,
+            RelativeDirectionInSubgrid(track_direction, *subgrid_data),
+            sizing_constraint, opt_needs_additional_pass);
+      });
+}
+
+void NGGridLayoutAlgorithm::CompleteTrackSizingAlgorithm(
+    const NGGridSizingTree& sizing_tree,
+    GridTrackSizingDirection track_direction,
+    SizingConstraint sizing_constraint,
+    bool* opt_needs_additional_pass) const {
+  CompleteTrackSizingAlgorithm(NGGridSizingSubtree(sizing_tree),
+                               /* opt_subgrid_data */ kNoSubgriddedItemData,
+                               track_direction, sizing_constraint,
+                               opt_needs_additional_pass);
+}
+
+template <typename CallbackFunc>
+void NGGridLayoutAlgorithm::ForEachSubgrid(
+    const NGGridSizingSubtree& sizing_subtree,
+    const CallbackFunc& callback_func) const {
+  auto& [grid_items, layout_data, subtree_size] =
+      sizing_subtree.SubtreeRootData();
+
+  // If we know this subtree doesn't have nested subgrids we can exit early
+  // instead of iterating over every grid item looking for them.
   if (subtree_size == 1) {
-    // If we know this subtree doesn't have nested subgrids we can exit early
-    // instead of iterating over every grid item looking for them.
     return;
   }
 
@@ -1896,31 +1905,18 @@
     const auto space = CreateConstraintSpaceForSubgridAlgorithm(subgrid_data);
     const auto fragment_geometry = CalculateInitialFragmentGeometry(
         space, subgrid_data->node, /* break_token */ nullptr,
-        /* is_intrinsic */ HasIndefiniteInlineSize(space));
+        /* is_intrinsic */ space.AvailableSize().inline_size ==
+            kIndefiniteSize);
 
     const NGGridLayoutAlgorithm subgrid_algorithm(
         {subgrid_data->node, fragment_geometry, space});
 
-    subgrid_algorithm.CompleteTrackSizingAlgorithm(
-        next_subgrid_subtree, subgrid_data,
-        RelativeDirectionInSubgrid(track_direction, grid_item),
-        sizing_constraint, opt_needs_additional_pass);
+    callback_func(subgrid_algorithm, next_subgrid_subtree, subgrid_data);
 
     next_subgrid_subtree = next_subgrid_subtree.NextSibling();
   }
 }
 
-void NGGridLayoutAlgorithm::CompleteTrackSizingAlgorithm(
-    const NGGridSizingTree& sizing_tree,
-    GridTrackSizingDirection track_direction,
-    SizingConstraint sizing_constraint,
-    bool* opt_needs_additional_pass) const {
-  CompleteTrackSizingAlgorithm(NGGridSizingSubtree(sizing_tree),
-                               /* opt_subgrid_data */ kNoSubgriddedItemData,
-                               track_direction, sizing_constraint,
-                               opt_needs_additional_pass);
-}
-
 LayoutUnit NGGridLayoutAlgorithm::ComputeSubgridContributionSize(
     const NGGridSizingSubtree& sizing_subtree,
     GridTrackSizingDirection track_direction,
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
index e8cdbbc9..931d00c4 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -161,6 +161,12 @@
       SizingConstraint sizing_constraint,
       bool* opt_needs_additional_pass = nullptr) const;
 
+  // Helper which iterates over the sizing tree, and instantiates a subgrid
+  // algorithm to invoke the callback with.
+  template <typename CallbackFunc>
+  void ForEachSubgrid(const NGGridSizingSubtree& sizing_subtree,
+                      const CallbackFunc& callback_func) const;
+
   LayoutUnit ComputeSubgridContributionSize(
       const NGGridSizingSubtree& sizing_subtree,
       GridTrackSizingDirection track_direction,
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
index 35e4088..943f123 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
@@ -273,6 +273,19 @@
  public:
   SharedStorageWorkletTest() = default;
 
+  void TearDown() override {
+    // Shut down the worklet gracefully. Otherwise, there could the a data race
+    // on accessing the base::FeatureList: the worklet thread may access the
+    // feature during SharedStorageWorkletGlobalScope::FinishOperation() or
+    // SharedStorageWorkletGlobalScope::NotifyContextDestroyed(), which can
+    // occur after the (maybe implicit) ScopedFeatureList is destroyed in the
+    // main thread.
+    shared_storage_worklet_service_.reset();
+    EXPECT_TRUE(worklet_terminated_future_.Wait());
+
+    PageTestBase::TearDown();
+  }
+
   AddModuleResult AddModule(const std::string& script_content,
                             std::string mime_type = "application/javascript") {
     InitializeWorkletServiceOnce();
@@ -2686,15 +2699,6 @@
         /*disabled_features=*/{});
   }
 
-  void TearDown() override {
-    // Shut down the worklet gracefully. Otherwise, the
-    // `private_aggregation_feature_` may be destroyed before the worklet thread
-    // (e.g. SharedStorageWorkletGlobalScope::NotifyContextDestroyed()) and some
-    // feature state assertions could fail.
-    shared_storage_worklet_service_.reset();
-    EXPECT_TRUE(worklet_terminated_future_.Wait());
-  }
-
   // `error_message` being `nullptr` indicates no error is expected.
   void ExecuteScriptAndValidateContribution(
       const std::string& script_body,
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index 2a3a065..a742b38 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -1024,21 +1024,24 @@
     return;
 
   FlushRecording(reason);
-  if (is_being_displayed_) {
-    ++frames_since_last_commit_;
-    // Make sure the GPU is never more than two animation frames behind.
-    constexpr unsigned kMaxCanvasAnimationBacklog = 2;
-    if (frames_since_last_commit_ >=
-        static_cast<int>(kMaxCanvasAnimationBacklog)) {
-      if (IsComposited() && !rate_limiter_) {
-        rate_limiter_ = std::make_unique<SharedContextRateLimiter>(
-            kMaxCanvasAnimationBacklog);
+  if (reason == CanvasResourceProvider::FlushReason::kCanvasPushFrame) {
+    if (is_being_displayed_) {
+      ++frames_since_last_commit_;
+      // Make sure the GPU is never more than two animation frames behind.
+      constexpr unsigned kMaxCanvasAnimationBacklog = 2;
+      if (frames_since_last_commit_ >=
+          static_cast<int>(kMaxCanvasAnimationBacklog)) {
+        if (IsComposited() && !rate_limiter_) {
+          rate_limiter_ = std::make_unique<SharedContextRateLimiter>(
+              kMaxCanvasAnimationBacklog);
+        }
       }
     }
-  }
 
-  if (rate_limiter_)
-    rate_limiter_->Tick();
+    if (rate_limiter_) {
+      rate_limiter_->Tick();
+    }
+  }
 }
 
 void Canvas2DLayerBridge::DoPaintInvalidation(const gfx::Rect& dirty_rect) {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
index 36054ac4..8c90ac8 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -1078,8 +1078,8 @@
   EXPECT_TRUE(bridge->IsValid());
   bridge->SetIsBeingDisplayed(true);
   EXPECT_FALSE(bridge->HasRateLimiterForTesting());
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
   EXPECT_TRUE(bridge->HasRateLimiterForTesting());
 }
 
@@ -1088,13 +1088,13 @@
       MakeBridge(gfx::Size(300, 150), RasterMode::kGPU, kNonOpaque);
   EXPECT_TRUE(bridge->IsValid());
   bridge->SetIsBeingDisplayed(true);
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
   EXPECT_TRUE(bridge->HasRateLimiterForTesting());
   bridge->SetIsBeingDisplayed(false);
   EXPECT_FALSE(bridge->HasRateLimiterForTesting());
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
-  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kTesting);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
+  bridge->FinalizeFrame(CanvasResourceProvider::FlushReason::kCanvasPushFrame);
   EXPECT_FALSE(bridge->HasRateLimiterForTesting());
 }
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
index 4ed57132..54cbe36 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -4,7 +4,6 @@
 
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h"
 
-#include "base/cpu_reduction_experiment.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
@@ -163,25 +162,6 @@
     queueing_delay_histograms_[static_cast<size_t>(queue->GetQueuePriority())]
         .CountMicroseconds(elapsed);
   }
-
-  // Don't log the metrics to evaluate impact of CPU reduction.
-  // This code is deemed not useful anymore (crbug.com/1181870).
-  // TODO(crbug.com/1295441: Fully remove the code once the experiment is over.
-  if (base::IsRunningCpuReductionExperiment()) {
-    return;
-  }
-
-  // WARNING: All code below must be compatible with down-sampling.
-  constexpr double kSamplingProbability = .01;
-  if (!metrics_subsampler_.ShouldSample(kSamplingProbability)) {
-    return;
-  }
-
-  base::TimeDelta duration = task_timing.wall_duration();
-  UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime2",
-                              base::saturated_cast<base::HistogramBase::Sample>(
-                                  duration.InMicroseconds()),
-                              1, 1000 * 1000, 50);
 }
 
 void MainThreadMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time,
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index d40be57..a97a6dc3 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2891,6 +2891,10 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/background-sync.https.html [ Timeout ]
+crbug.com/626703 [ Mac13 ] virtual/pending-beacon/external/wpt/pending-beacon/pending_beacon-sendonhidden.tentative.https.window.html [ Timeout ]
+crbug.com/626703 [ Mac12 ] virtual/prefetch/external/wpt/speculation-rules/prefetch/different-initiators-2.https.html [ Timeout ]
+crbug.com/626703 [ Mac13 ] virtual/prefetch/external/wpt/speculation-rules/prefetch/out-of-document-rule-set.https.html?include=RelativeUrlForCandidate [ Timeout ]
 crbug.com/626703 external/wpt/css/css-images/image-set/image-set-negative-resolution-rendering-2.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-images/image-set/image-set-negative-resolution-rendering.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-nesting/conditional-rules.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 531153992..2886ea3 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -18243,6 +18243,19 @@
        {}
       ]
      ],
+     "transform-001-print.html": [
+      "f19b889d07ba01219b14b4a3c11c8ab545d10e20",
+      [
+       null,
+       [
+        [
+         "/css/printing/transform-001-print-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "transition-in-media-print.tentative.html": [
       "54bac1f48124a27689dc2f614003d462fe2dd477",
       [
@@ -271558,11 +271571,11 @@
   "support": {
    ".cache": {
     "gitignore2.json": [
-     "394444bb1cdbe21e7213c8e1433df4bb86593f1c",
+     "5bea07f2768ec69d90538e09cbb1c85d76b2f755",
      []
     ],
     "mtime.json": [
-     "4eca8882ddc98f90b699b5d307f7ab8adb8ba201",
+     "f1b5cf74ee5df497a766b77a0590606e50e1f9b4",
      []
     ]
    },
@@ -288694,7 +288707,7 @@
        []
       ],
       "border-shorthand-expected.txt": [
-       "f78d14d1f75bbaeb39b547fa94bd3498e7f45f1b",
+       "a640f528e4cc2ae4436086cc359078a13ead216c",
        []
       ],
       "border-shorthand.html.ini": [
@@ -290415,6 +290428,10 @@
        "27b0cdc2b9eb77f0cd679e8439a8c752b08ab9d3",
        []
       ],
+      "single-line-column-flex-fragmentation-026.html.ini": [
+       "39ebbf7bbe5f3f16ab23cfd5a767a07a9b4ed0fb",
+       []
+      ],
       "single-line-column-flex-fragmentation-038.html.ini": [
        "6fe44b44aafc9e806b4c79ab64836b439d117537",
        []
@@ -325783,7 +325800,7 @@
       []
      ],
      "preserve3d-and-flattening-z-order-006.html.ini": [
-      "742b4b38e8fd59687657c1c7f2200b604afff8d9",
+      "bdb0fc50b32156b623f5874c50dacb5a87437bbb",
       []
      ],
      "preserve3d-and-flattening-z-order-008.html.ini": [
@@ -328487,6 +328504,10 @@
        "f02ebb3eec8464a6ab39755b763823818cffe54c",
        []
       ],
+      "kind-of-widget-fallback-color-input-border-image-width-001.html.ini": [
+       "fce7085a97394cc160e7dc62b707655044e1db5f",
+       []
+      ],
       "kind-of-widget-fallback-color-input-border-inline-end-style-001.html.ini": [
        "5bc56d3cf7154da70ff2a8de32d4ff3b697314c2",
        []
@@ -328632,7 +328653,7 @@
        []
       ],
       "kind-of-widget-fallback-input-reset-border-right-color-001.html.ini": [
-       "5d52fb62d1f654018a4cbeacb1c79106ecdb770a",
+       "2a370064f46198c7f5b21776ae6b4698ae4350dc",
        []
       ],
       "kind-of-widget-fallback-input-reset-border-right-width-001.html.ini": [
@@ -337332,6 +337353,10 @@
        []
       ]
      },
+     "transform-001-print-ref.html": [
+      "45c3abf1810a55dc760058bf5fcc3064f3bac188",
+      []
+     ],
      "transition-in-media-print-ref.html": [
       "2f25c06131e9372512e23ab9ff8428c594f74391",
       []
@@ -356006,6 +356031,10 @@
       "8bbfe82e86664eb309488988de06b09813bc4d57",
       []
      ],
+     "popup-redirect-same-origin-allow-popups.https.html.ini": [
+      "0756fe5b2f9816e2348e2320550f3c4231b313f4",
+      []
+     ],
      "popup-same-origin-allow-popups-with-cross-origin.https.html.headers": [
       "d83ed86fb9b5d159b9f380424887402edc96cb75",
       []
@@ -382049,7 +382078,7 @@
       []
      ],
      "view-timeline-lookup-expected.txt": [
-      "58d0663a9332f29ca1c3b452b6f74f9791387d8d",
+      "90b79f207ebb0dbbc60f8420a71bb4b04baf9ad0",
       []
      ],
      "view-timeline-lookup.html.ini": [
@@ -390884,15 +390913,27 @@
      []
     ],
     "urlsearchparams-delete.any-expected.txt": [
-     "2e788491cee9e3a84ec463ae936a0bb874558c00",
+     "1af29c1937a322794722aea6f3fc5d69f5679d8e",
      []
     ],
     "urlsearchparams-delete.any.js.ini": [
-     "9f22a447d7a66f9514b01ba4102d38c7aff7d171",
+     "c7ebe7db0f6f690b27b845c332019a6b4b588b40",
      []
     ],
     "urlsearchparams-delete.any.worker-expected.txt": [
-     "2e788491cee9e3a84ec463ae936a0bb874558c00",
+     "1af29c1937a322794722aea6f3fc5d69f5679d8e",
+     []
+    ],
+    "urlsearchparams-has.any-expected.txt": [
+     "b156cd4cd3c9a4803dcf826233db5ba3d6579e91",
+     []
+    ],
+    "urlsearchparams-has.any.js.ini": [
+     "41e60afed198e870438df1c93e06969e6b789d7e",
+     []
+    ],
+    "urlsearchparams-has.any.worker-expected.txt": [
+     "b156cd4cd3c9a4803dcf826233db5ba3d6579e91",
      []
     ],
     "urlsearchparams-size.any.js.ini": [
@@ -439867,7 +439908,7 @@
        ]
       ],
       "border-shorthand.html": [
-       "30491a534ec65abd673a80a278c3f6aa47f82220",
+       "487ce876fa51eec3bb7d10cdf48203809ef3a6a6",
        [
         null,
         {}
@@ -440799,6 +440840,13 @@
        {}
       ]
      ],
+     "transform-011.html": [
+      "58008e509ead3be32d8a4f14149dec44b6e47306",
+      [
+       null,
+       {}
+      ]
+     ],
      "widows-orphans-005.html": [
       "713849703ce92e062780bd20e0708c8dfcd21f5f",
       [
@@ -600371,7 +600419,7 @@
       ]
      ],
      "view-timeline-animation.html": [
-      "73189b85917314e497cf0cb70d2e22986c230997",
+      "a367ef9dd879544e1fc0ad6f850661c86d2ea8e2",
       [
        null,
        {}
@@ -600413,7 +600461,7 @@
       ]
      ],
      "view-timeline-dynamic.html": [
-      "76a30ad56603771c67b2325d2e13aed4a654b658",
+      "207c8c4e22379e19cf2f557d89295e34178e0a5b",
       [
        null,
        {}
@@ -600448,7 +600496,7 @@
       ]
      ],
      "view-timeline-lookup.html": [
-      "b8a5b0008be1a0b9285fd52b3ecd666f39ab6a3e",
+      "6cead9dc586697428c21d1f3fcca9c7b047f4a7d",
       [
        null,
        {}
@@ -605311,7 +605359,7 @@
       ]
      ],
      "navigation-timing.https.html": [
-      "6b51a5c2da213eb27cf0d9fd401b7c49b5349950",
+      "75cab40458c6d362caa34315388ad762fbb7d2e9",
       [
        null,
        {}
@@ -622310,7 +622358,7 @@
      ]
     ],
     "urlsearchparams-delete.any.js": [
-     "28ebbce5f13bd8de759a4a1c623e7a36a0e309df",
+     "f9c623b90b175d8811ed7ce3a6bc5e569a730ad7",
      [
       "url/urlsearchparams-delete.any.html",
       {}
@@ -622354,7 +622402,7 @@
      ]
     ],
     "urlsearchparams-has.any.js": [
-     "673dce77dc44ab6f78bf713d196c0ea5b588a28d",
+     "54cbf286db4a3d21fb764a1c93b7a16d34c47486",
      [
       "url/urlsearchparams-has.any.html",
       {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-026.html.ini b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-026.html.ini
new file mode 100644
index 0000000..39ebbf7b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/single-line-column-flex-fragmentation-026.html.ini
@@ -0,0 +1,3 @@
+[single-line-column-flex-fragmentation-026.html]
+  expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html.ini
index 742b4b3..bdb0fc50 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html.ini
@@ -1,3 +1,4 @@
 [preserve3d-and-flattening-z-order-006.html]
   expected:
+    if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL
     if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-image-width-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-image-width-001.html.ini
new file mode 100644
index 0000000..fce7085
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-color-input-border-image-width-001.html.ini
@@ -0,0 +1,3 @@
+[kind-of-widget-fallback-color-input-border-image-width-001.html]
+  expected:
+    if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-right-color-001.html.ini b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-right-color-001.html.ini
index 5d52fb62..2a370064 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-right-color-001.html.ini
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-reset-border-right-color-001.html.ini
@@ -1,4 +1,4 @@
 [kind-of-widget-fallback-input-reset-border-right-color-001.html]
   expected:
-    if (product == "content_shell") and (os == "win") and (port == "win11"): FAIL
+    if (product == "content_shell") and (os == "win"): FAIL
     if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-same-origin-allow-popups.https.html.ini b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-same-origin-allow-popups.https.html.ini
new file mode 100644
index 0000000..0756fe5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/popup-redirect-same-origin-allow-popups.https.html.ini
@@ -0,0 +1,3 @@
+[popup-redirect-same-origin-allow-popups.https.html]
+  expected:
+    if product == "chrome": [ERROR, OK]
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any-expected.txt b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any-expected.txt
index 2e788491..1af29c1 100644
--- a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any-expected.txt
@@ -5,5 +5,6 @@
 PASS Removing non-existent param removes ? from URL
 FAIL Changing the query of a URL with an opaque path can impact the path assert_equals: expected "space" but got "space    "
 PASS Changing the query of a URL with an opaque path can impact the path if the URL has no fragment
+FAIL Two-argument delete() assert_equals: expected "a=b&a=d" but got ""
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js
index 28ebbce..f9c623b 100644
--- a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js
@@ -61,3 +61,12 @@
   assert_equals(url.pathname, 'space    ');
   assert_equals(url.href, 'data:space    #test');
 }, 'Changing the query of a URL with an opaque path can impact the path if the URL has no fragment');
+
+test(() => {
+  const params = new URLSearchParams();
+  params.append('a', 'b');
+  params.append('a', 'c');
+  params.append('a', 'd');
+  params.delete('a', 'c');
+  assert_equals(params.toString(), 'a=b&a=d');
+}, "Two-argument delete()");
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js.ini b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js.ini
index 9f22a447..c7ebe7db0 100644
--- a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js.ini
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.js.ini
@@ -2,7 +2,13 @@
   [Changing the query of a URL with an opaque path can impact the path]
     expected: FAIL
 
+  [Two-argument delete()]
+    expected: FAIL
+
 
 [urlsearchparams-delete.any.worker.html]
   [Changing the query of a URL with an opaque path can impact the path]
     expected: FAIL
+
+  [Two-argument delete()]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.worker-expected.txt
index 2e788491..1af29c1 100644
--- a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-delete.any.worker-expected.txt
@@ -5,5 +5,6 @@
 PASS Removing non-existent param removes ? from URL
 FAIL Changing the query of a URL with an opaque path can impact the path assert_equals: expected "space" but got "space    "
 PASS Changing the query of a URL with an opaque path can impact the path if the URL has no fragment
+FAIL Two-argument delete() assert_equals: expected "a=b&a=d" but got ""
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any-expected.txt b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any-expected.txt
new file mode 100644
index 0000000..b156cd4c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Has basics
+PASS has() following delete()
+FAIL Two-argument has() assert_false: expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js
index 673dce7..54cbf28 100644
--- a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js
@@ -22,3 +22,16 @@
     params.delete('first');
     assert_false(params.has('first'), 'Search params object has no name "first"');
 }, 'has() following delete()');
+
+test(() => {
+  const params = new URLSearchParams("a=b&a=d&c&e&");
+  assert_true(params.has('a', 'b'));
+  assert_false(params.has('a', 'c'));
+  assert_true(params.has('a', 'd'));
+  assert_true(params.has('e', ''));
+  params.append('first', null);
+  assert_false(params.has('first', ''));
+  assert_true(params.has('first', 'null'));
+  params.delete('a', 'b');
+  assert_true(params.has('a', 'd'));
+}, "Two-argument has()");
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js.ini b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js.ini
new file mode 100644
index 0000000..41e60af
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.js.ini
@@ -0,0 +1,8 @@
+[urlsearchparams-has.any.html]
+  [Two-argument has()]
+    expected: FAIL
+
+
+[urlsearchparams-has.any.worker.html]
+  [Two-argument has()]
+    expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.worker-expected.txt
new file mode 100644
index 0000000..b156cd4c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/url/urlsearchparams-has.any.worker-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Has basics
+PASS has() following delete()
+FAIL Two-argument has() assert_false: expected false got true
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue-expected.txt
new file mode 100644
index 0000000..daea638
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue-expected.txt
@@ -0,0 +1,3 @@
+Verifies that Streaming declarative shadow DOM (<template shadowrootmode>) does not trigger a deprecation issue.
+Success - no issues reported
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue.js
new file mode 100644
index 0000000..20098a0d
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/streaming-declarative-shadow-dom-issue.js
@@ -0,0 +1,22 @@
+(async function (testRunner) {
+  const { session, dp } = await testRunner.startBlank(
+  'Verifies that Streaming declarative shadow DOM (<template shadowrootmode>) does not trigger a deprecation issue.');
+  await dp.Audits.enable();
+  const issueAdded = dp.Audits.onceIssueAdded();
+
+  await session.navigate('../resources/streaming-declarative-shadow-dom.html');
+
+  // This is a test that issues are NOT reported. So we need to just wait
+  // for a period of time.
+  let timedOut = false;
+  const timeout = new Promise(resolve => setTimeout(() => {
+    timedOut = true;
+    resolve();
+  }, 100));
+  await Promise.race([
+    timeout,
+    issueAdded,
+  ]);
+  testRunner.log(timedOut ? "Success - no issues reported" : "FAIL: issues reported.");
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/streaming-declarative-shadow-dom.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/streaming-declarative-shadow-dom.html
new file mode 100644
index 0000000..0e7adb5
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/streaming-declarative-shadow-dom.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+
+<div><template shadowrootmode=open>NON-Deprecated Shadow Root</template></div>
diff --git a/third_party/blink/web_tests/platform/mac/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac12/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/mac/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac12/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac13-arm64/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt
deleted file mode 100644
index 6c9a04cb..0000000
--- a/third_party/blink/web_tests/platform/mac-mac13-arm64/wpt_internal/mediastream/mediastreamtrackprocessor-transfer-to-worker-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Test we can transfer a Video MediaStreamTrackProcessor stream
-PASS Test we can transfer an Audio MediaStreamTrackProcessor stream
-Harness: the test ran to completion.
-
diff --git a/third_party/cpuinfo/cpuinfo.gni b/third_party/cpuinfo/cpuinfo.gni
new file mode 100644
index 0000000..be4e155
--- /dev/null
+++ b/third_party/cpuinfo/cpuinfo.gni
@@ -0,0 +1,16 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+use_cpuinfo =
+    # cpuinfo is not supported on these chips.
+    current_cpu != "ppc64" && current_cpu != "ppc64le" &&
+    current_cpu != "s390" && current_cpu != "s390x" &&
+    # cpuinfo is not supported on fuchsia.
+    !is_fuchsia &&
+    # There's a few arm architectures that are not supported by cpuinfo,
+    # especially amongst ChromeOS devices.
+    # See //third_party/cpuinfo/src/src/arm/linux/cp.h.
+    (!defined(arm_arch) ||
+     (arm_arch != "armv7-a+crc" && arm_arch != "armv8-a+crc" &&
+      arm_arch != "armv8-a+crc+crypto"))
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium
index 951355f7..8e276552 100644
--- a/third_party/libaom/README.chromium
+++ b/third_party/libaom/README.chromium
@@ -2,8 +2,8 @@
 Short Name: libaom
 URL: https://aomedia.googlesource.com/aom/
 Version: 0
-Date: Tuesday April 18 2023
-Revision: 5a0903824082f41123e8365b5b99ddb6ced8971c
+Date: Thursday May 04 2023
+Revision: b6cfc3cf4551515edd75eb57b77837b58cdba8f4
 CPEPrefix: cpe:/a:aomedia:aomedia:3.6.0
 License: BSD
 License File: source/libaom/LICENSE
diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs.gni
index 8481fc4..3d5484ef 100644
--- a/third_party/libaom/libaom_srcs.gni
+++ b/third_party/libaom/libaom_srcs.gni
@@ -203,6 +203,7 @@
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_error_neon.c",
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/encodetxb_neon.c",
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/hybrid_fwd_txfm_neon.c",
+  "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_k_means_neon.c",
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_fwd_txfm2d_neon.c",
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/highbd_fwd_txfm_neon.c",
   "//third_party/libaom/source/libaom/av1/encoder/arm/neon/wedge_utils_neon.c",
@@ -377,6 +378,35 @@
   "//third_party/libaom/source/libaom/third_party/vector/vector.h",
 ]
 
+aom_common_app_util_sources = [
+  "//third_party/libaom/source/libaom/av1/arg_defs.c",
+  "//third_party/libaom/source/libaom/av1/arg_defs.h",
+  "//third_party/libaom/source/libaom/common/args.c",
+  "//third_party/libaom/source/libaom/common/args.h",
+  "//third_party/libaom/source/libaom/common/args_helper.c",
+  "//third_party/libaom/source/libaom/common/args_helper.h",
+  "//third_party/libaom/source/libaom/common/av1_config.c",
+  "//third_party/libaom/source/libaom/common/av1_config.h",
+  "//third_party/libaom/source/libaom/common/ivfdec.c",
+  "//third_party/libaom/source/libaom/common/ivfdec.h",
+  "//third_party/libaom/source/libaom/common/md5_utils.c",
+  "//third_party/libaom/source/libaom/common/md5_utils.h",
+  "//third_party/libaom/source/libaom/common/rawenc.c",
+  "//third_party/libaom/source/libaom/common/rawenc.h",
+  "//third_party/libaom/source/libaom/common/tools_common.c",
+  "//third_party/libaom/source/libaom/common/tools_common.h",
+  "//third_party/libaom/source/libaom/common/video_common.h",
+  "//third_party/libaom/source/libaom/common/y4menc.c",
+  "//third_party/libaom/source/libaom/common/y4menc.h",
+]
+
+aom_decoder_app_util_sources = [
+  "//third_party/libaom/source/libaom/common/obudec.c",
+  "//third_party/libaom/source/libaom/common/obudec.h",
+  "//third_party/libaom/source/libaom/common/video_reader.c",
+  "//third_party/libaom/source/libaom/common/video_reader.h",
+]
+
 aom_dsp_common_asm_sse2 = [
   "//third_party/libaom/source/libaom/aom_dsp/x86/aom_high_subpixel_8t_sse2.asm",
   "//third_party/libaom/source/libaom/aom_dsp/x86/aom_high_subpixel_bilinear_sse2.asm",
@@ -609,6 +639,19 @@
   "//third_party/libaom/source/libaom/aom_dsp/variance.h",
 ]
 
+aom_encoder_app_util_sources = [
+  "//third_party/libaom/source/libaom/common/ivfenc.c",
+  "//third_party/libaom/source/libaom/common/ivfenc.h",
+  "//third_party/libaom/source/libaom/common/video_writer.c",
+  "//third_party/libaom/source/libaom/common/video_writer.h",
+  "//third_party/libaom/source/libaom/common/warnings.c",
+  "//third_party/libaom/source/libaom/common/warnings.h",
+  "//third_party/libaom/source/libaom/common/y4minput.c",
+  "//third_party/libaom/source/libaom/common/y4minput.h",
+  "//third_party/libaom/source/libaom/examples/encoder_util.c",
+  "//third_party/libaom/source/libaom/examples/encoder_util.h",
+]
+
 aom_encoder_stats_sources = [
   "//third_party/libaom/source/libaom/stats/aomstats.c",
   "//third_party/libaom/source/libaom/stats/aomstats.h",
@@ -616,6 +659,23 @@
   "//third_party/libaom/source/libaom/stats/rate_hist.h",
 ]
 
+aom_libwebm_sources = [
+  "//third_party/libaom/source/libaom/third_party/libwebm/common/hdr_util.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/common/hdr_util.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/common/webmids.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvmuxer.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvmuxer.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvmuxertypes.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvmuxerutil.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvwriter.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvmuxer/mkvwriter.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvparser/mkvparser.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvparser/mkvparser.h",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvparser/mkvreader.cc",
+  "//third_party/libaom/source/libaom/third_party/libwebm/mkvparser/mkvreader.h",
+]
+
 aom_mem_sources = [
   "//third_party/libaom/source/libaom/aom_mem/aom_mem.c",
   "//third_party/libaom/source/libaom/aom_mem/aom_mem.h",
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h
index 0ab93ec..218b492 100644
--- a/third_party/libaom/source/config/config/aom_version.h
+++ b/third_party/libaom/source/config/config/aom_version.h
@@ -12,8 +12,8 @@
 #define VERSION_MAJOR 3
 #define VERSION_MINOR 6
 #define VERSION_PATCH 0
-#define VERSION_EXTRA "516-g5a0903824"
+#define VERSION_EXTRA "581-gb6cfc3cf4"
 #define VERSION_PACKED \
   ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH))
-#define VERSION_STRING_NOSP "3.6.0-516-g5a0903824"
-#define VERSION_STRING " 3.6.0-516-g5a0903824"
+#define VERSION_STRING_NOSP "3.6.0-581-gb6cfc3cf4"
+#define VERSION_STRING " 3.6.0-581-gb6cfc3cf4"
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm
index 56f39b6..0dcda7b 100644
--- a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm
+++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h
index ad39421..8afb854d 100644
--- a/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h
+++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/ios/arm-neon/config/aom_dsp_rtcd.h
index cc9741db..1db5fff 100644
--- a/third_party/libaom/source/config/ios/arm-neon/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/ios/arm-neon/config/aom_dsp_rtcd.h
@@ -54,7 +54,16 @@
 #define aom_comp_avg_pred aom_comp_avg_pred_neon
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+#define aom_comp_mask_pred aom_comp_mask_pred_neon
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -74,45 +83,89 @@
 #define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_neon
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_neon
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_neon
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_neon
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_neon
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_neon
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_neon
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_neon
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_neon
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_neon
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_neon
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -122,13 +175,25 @@
 #define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_neon
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_neon
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_neon
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_neon
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -139,45 +204,89 @@
 #define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_neon
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_neon
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_neon
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_neon
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_neon
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_neon
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_neon
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_neon
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_neon
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_neon
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_neon
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -187,13 +296,25 @@
 #define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_neon
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_neon
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_neon
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_neon
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -204,45 +325,89 @@
 #define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_neon
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_neon
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_neon
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_neon
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_neon
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_neon
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_neon
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_neon
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_neon
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_neon
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_neon
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -252,13 +417,25 @@
 #define aom_dc_predictor_64x64 aom_dc_predictor_64x64_neon
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_neon
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_neon
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_neon
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -269,45 +446,89 @@
 #define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_neon
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_neon
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_neon
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_neon
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_neon
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_neon
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_neon
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_neon
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_neon
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_neon
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_neon
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -317,13 +538,25 @@
 #define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_neon
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_neon
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_neon
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_neon
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -470,57 +703,117 @@
 #define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_neon
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_neon
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_neon
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_neon
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_neon
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_neon
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_neon
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_neon
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_neon
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_neon
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_neon
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_neon
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_neon
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_neon
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_neon
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -790,52 +1083,241 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x128 \
+  aom_masked_sub_pixel_variance128x128_neon
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x64 \
+  aom_masked_sub_pixel_variance128x64_neon
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x16 \
+  aom_masked_sub_pixel_variance16x16_neon
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x32 \
+  aom_masked_sub_pixel_variance16x32_neon
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_neon
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x16 \
+  aom_masked_sub_pixel_variance32x16_neon
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x32 \
+  aom_masked_sub_pixel_variance32x32_neon
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x64 \
+  aom_masked_sub_pixel_variance32x64_neon
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_neon
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_neon
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x128 \
+  aom_masked_sub_pixel_variance64x128_neon
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x32 \
+  aom_masked_sub_pixel_variance64x32_neon
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x64 \
+  aom_masked_sub_pixel_variance64x64_neon
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_neon
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_neon
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_neon
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -972,9 +1454,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_neon
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_neon
@@ -990,9 +1469,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_neon
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_neon
@@ -1008,9 +1484,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_neon
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_neon
@@ -1026,9 +1499,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_neon
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_neon
@@ -1044,9 +1514,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_neon
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_neon
@@ -1062,9 +1529,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_neon
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_neon
@@ -1080,9 +1544,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_neon
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_neon
@@ -1098,9 +1559,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_neon
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_neon
@@ -1116,9 +1574,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_neon
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_neon
@@ -1134,9 +1589,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_neon
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_neon
@@ -1152,9 +1604,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_neon
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_neon
@@ -1170,9 +1619,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_neon
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_neon
@@ -1188,9 +1634,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_neon
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_neon
@@ -1206,9 +1649,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_neon
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_neon
@@ -1224,9 +1664,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_neon
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_neon
@@ -1242,9 +1679,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_neon
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_neon
@@ -1764,57 +2198,117 @@
 #define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_neon
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_neon
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_neon
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_neon
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_neon
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_neon
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_neon
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_neon
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_neon
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_neon
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_neon
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_neon
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_neon
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_neon
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_neon
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
diff --git a/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h b/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h
index 6dfd871..99a0c0a 100644
--- a/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/ios/arm-neon/config/av1_rtcd.h
@@ -127,10 +127,22 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim1 av1_calc_indices_dim1_neon
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim2 av1_calc_indices_dim2_neon
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_config.asm b/third_party/libaom/source/config/ios/arm64/config/aom_config.asm
index 56f39b6..0dcda7b 100644
--- a/third_party/libaom/source/config/ios/arm64/config/aom_config.asm
+++ b/third_party/libaom/source/config/ios/arm64/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_config.h b/third_party/libaom/source/config/ios/arm64/config/aom_config.h
index ad39421..8afb854d 100644
--- a/third_party/libaom/source/config/ios/arm64/config/aom_config.h
+++ b/third_party/libaom/source/config/ios/arm64/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/ios/arm64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/ios/arm64/config/aom_dsp_rtcd.h
index cc9741db..1db5fff 100644
--- a/third_party/libaom/source/config/ios/arm64/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/ios/arm64/config/aom_dsp_rtcd.h
@@ -54,7 +54,16 @@
 #define aom_comp_avg_pred aom_comp_avg_pred_neon
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+#define aom_comp_mask_pred aom_comp_mask_pred_neon
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -74,45 +83,89 @@
 #define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_neon
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_neon
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_neon
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_neon
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_neon
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_neon
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_neon
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_neon
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_neon
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_neon
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_neon
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -122,13 +175,25 @@
 #define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_neon
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_neon
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_neon
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_neon
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -139,45 +204,89 @@
 #define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_neon
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_neon
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_neon
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_neon
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_neon
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_neon
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_neon
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_neon
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_neon
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_neon
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_neon
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -187,13 +296,25 @@
 #define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_neon
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_neon
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_neon
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_neon
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -204,45 +325,89 @@
 #define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_neon
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_neon
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_neon
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_neon
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_neon
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_neon
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_neon
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_neon
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_neon
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_neon
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_neon
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -252,13 +417,25 @@
 #define aom_dc_predictor_64x64 aom_dc_predictor_64x64_neon
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_neon
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_neon
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_neon
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -269,45 +446,89 @@
 #define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_neon
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_neon
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_neon
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_neon
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_neon
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_neon
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_neon
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_neon
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_neon
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_neon
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_neon
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -317,13 +538,25 @@
 #define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_neon
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_neon
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_neon
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_neon
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -470,57 +703,117 @@
 #define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_neon
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_neon
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_neon
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_neon
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_neon
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_neon
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_neon
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_neon
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_neon
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_neon
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_neon
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_neon
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_neon
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_neon
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_neon
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -790,52 +1083,241 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x128 \
+  aom_masked_sub_pixel_variance128x128_neon
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x64 \
+  aom_masked_sub_pixel_variance128x64_neon
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x16 \
+  aom_masked_sub_pixel_variance16x16_neon
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x32 \
+  aom_masked_sub_pixel_variance16x32_neon
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_neon
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x16 \
+  aom_masked_sub_pixel_variance32x16_neon
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x32 \
+  aom_masked_sub_pixel_variance32x32_neon
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x64 \
+  aom_masked_sub_pixel_variance32x64_neon
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_neon
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_neon
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x128 \
+  aom_masked_sub_pixel_variance64x128_neon
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x32 \
+  aom_masked_sub_pixel_variance64x32_neon
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x64 \
+  aom_masked_sub_pixel_variance64x64_neon
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_neon
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_neon
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_neon
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -972,9 +1454,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_neon
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_neon
@@ -990,9 +1469,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_neon
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_neon
@@ -1008,9 +1484,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_neon
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_neon
@@ -1026,9 +1499,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_neon
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_neon
@@ -1044,9 +1514,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_neon
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_neon
@@ -1062,9 +1529,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_neon
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_neon
@@ -1080,9 +1544,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_neon
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_neon
@@ -1098,9 +1559,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_neon
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_neon
@@ -1116,9 +1574,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_neon
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_neon
@@ -1134,9 +1589,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_neon
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_neon
@@ -1152,9 +1604,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_neon
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_neon
@@ -1170,9 +1619,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_neon
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_neon
@@ -1188,9 +1634,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_neon
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_neon
@@ -1206,9 +1649,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_neon
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_neon
@@ -1224,9 +1664,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_neon
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_neon
@@ -1242,9 +1679,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_neon
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_neon
@@ -1764,57 +2198,117 @@
 #define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_neon
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_neon
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_neon
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_neon
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_neon
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_neon
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_neon
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_neon
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_neon
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_neon
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_neon
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_neon
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_neon
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_neon
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_neon
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
diff --git a/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h
index 6dfd871..99a0c0a 100644
--- a/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/ios/arm64/config/av1_rtcd.h
@@ -127,10 +127,22 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim1 av1_calc_indices_dim1_neon
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim2 av1_calc_indices_dim2_neon
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
index d3203ad..41de0436 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
index c68ea102..8ab533e 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
index 01cd0b5fe..5d29310 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_dsp_rtcd.h
@@ -59,7 +59,24 @@
                                       int ref_stride);
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+RTCD_EXTERN void (*aom_comp_mask_pred)(uint8_t* comp_pred,
+                                       const uint8_t* pred,
+                                       int width,
+                                       int height,
+                                       const uint8_t* ref,
+                                       int ref_stride,
+                                       const uint8_t* mask,
+                                       int mask_stride,
+                                       int invert_mask);
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -79,45 +96,122 @@
 RTCD_EXTERN void (*aom_dc_128_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_16x32)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_16x4)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_16x64)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_16x8)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_32x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_128_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_32x64)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_32x8)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_4x16)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_128_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_4x8)(uint8_t* dst,
+                                             ptrdiff_t y_stride,
+                                             const uint8_t* above,
+                                             const uint8_t* left);
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_64x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_64x32)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -130,13 +224,34 @@
                                                const uint8_t* left);
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_8x16)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_8x32)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_128_predictor_8x4)(uint8_t* dst,
+                                             ptrdiff_t y_stride,
+                                             const uint8_t* above,
+                                             const uint8_t* left);
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -147,45 +262,122 @@
 RTCD_EXTERN void (*aom_dc_left_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_16x32)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_16x4)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_16x64)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_16x8)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_32x16)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_left_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_32x64)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_32x8)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_4x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_left_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_4x8)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_64x16)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_64x32)(uint8_t* dst,
+                                                ptrdiff_t y_stride,
+                                                const uint8_t* above,
+                                                const uint8_t* left);
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -198,13 +390,34 @@
                                                 const uint8_t* left);
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_8x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_8x32)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_left_predictor_8x4)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -215,45 +428,122 @@
 RTCD_EXTERN void (*aom_dc_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_16x32)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_16x4)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_16x64)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_16x8)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_32x16)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_32x64)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_32x8)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_4x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_4x8)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_64x16)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_64x32)(uint8_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint8_t* above,
+                                           const uint8_t* left);
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -266,13 +556,34 @@
                                            const uint8_t* left);
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_8x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_8x32)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_predictor_8x4)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -283,45 +594,122 @@
 RTCD_EXTERN void (*aom_dc_top_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_16x32)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_16x4)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_16x64)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_16x8)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_32x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_top_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_32x64)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_32x8)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_4x16)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_dc_top_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_4x8)(uint8_t* dst,
+                                             ptrdiff_t y_stride,
+                                             const uint8_t* above,
+                                             const uint8_t* left);
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_64x16)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_64x32)(uint8_t* dst,
+                                               ptrdiff_t y_stride,
+                                               const uint8_t* above,
+                                               const uint8_t* left);
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -334,13 +722,34 @@
                                                const uint8_t* left);
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_8x16)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_8x32)(uint8_t* dst,
+                                              ptrdiff_t y_stride,
+                                              const uint8_t* above,
+                                              const uint8_t* left);
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+RTCD_EXTERN void (*aom_dc_top_predictor_8x4)(uint8_t* dst,
+                                             ptrdiff_t y_stride,
+                                             const uint8_t* above,
+                                             const uint8_t* left);
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -487,57 +896,162 @@
 RTCD_EXTERN void (*aom_h_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_16x32)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_16x4)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_16x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_16x8)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_32x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_h_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_32x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_32x8)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_4x16)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_h_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_4x8)(uint8_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint8_t* above,
+                                        const uint8_t* left);
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_64x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_64x32)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_64x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_8x16)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_8x32)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+RTCD_EXTERN void (*aom_h_predictor_8x4)(uint8_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint8_t* above,
+                                        const uint8_t* left);
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -807,52 +1321,407 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance128x128)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance128x64)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance16x16)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance16x32)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance16x8)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance32x16)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance32x32)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance32x64)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance4x4)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance4x8)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance64x128)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance64x32)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance64x64)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance8x16)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance8x4)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+RTCD_EXTERN unsigned int (*aom_masked_sub_pixel_variance8x8)(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -994,9 +1863,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad128x64)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1012,9 +1878,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad16x16)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1030,9 +1893,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad16x32)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1048,9 +1908,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad16x8)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1066,9 +1923,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad32x16)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1084,9 +1938,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad32x32)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1102,9 +1953,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad32x64)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1120,9 +1968,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad4x4)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1138,9 +1983,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad4x4x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad4x8)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1156,9 +1998,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad4x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad64x128)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1174,9 +2013,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad64x32)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1192,9 +2028,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad64x64)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1210,9 +2043,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad8x16)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1228,9 +2058,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad8x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad8x4)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1246,9 +2073,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad8x4x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad8x8)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1264,9 +2088,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad8x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 RTCD_EXTERN unsigned int (*aom_sad_skip_128x128)(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1786,57 +2607,162 @@
 RTCD_EXTERN void (*aom_v_predictor_16x16)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_16x32)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_16x4)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_16x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_16x8)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_32x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_v_predictor_32x32)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_32x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_32x8)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_4x16)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 RTCD_EXTERN void (*aom_v_predictor_4x4)(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_4x8)(uint8_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint8_t* above,
+                                        const uint8_t* left);
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_64x16)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_64x32)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_64x64)(uint8_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint8_t* above,
+                                          const uint8_t* left);
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_8x16)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_8x32)(uint8_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint8_t* above,
+                                         const uint8_t* left);
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+RTCD_EXTERN void (*aom_v_predictor_8x4)(uint8_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint8_t* above,
+                                        const uint8_t* left);
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -1951,54 +2877,282 @@
     if (flags & HAS_NEON) {
       aom_comp_avg_pred = aom_comp_avg_pred_neon;
     }
+    aom_comp_mask_pred = aom_comp_mask_pred_c;
+    if (flags & HAS_NEON) {
+      aom_comp_mask_pred = aom_comp_mask_pred_neon;
+    }
     aom_convolve_copy = aom_convolve_copy_c;
     if (flags & HAS_NEON) aom_convolve_copy = aom_convolve_copy_neon;
     aom_dc_128_predictor_16x16 = aom_dc_128_predictor_16x16_c;
     if (flags & HAS_NEON) aom_dc_128_predictor_16x16 = aom_dc_128_predictor_16x16_neon;
+    aom_dc_128_predictor_16x32 = aom_dc_128_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_16x32 = aom_dc_128_predictor_16x32_neon;
+    }
+    aom_dc_128_predictor_16x4 = aom_dc_128_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_16x4 = aom_dc_128_predictor_16x4_neon;
+    }
+    aom_dc_128_predictor_16x64 = aom_dc_128_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_16x64 = aom_dc_128_predictor_16x64_neon;
+    }
+    aom_dc_128_predictor_16x8 = aom_dc_128_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_16x8 = aom_dc_128_predictor_16x8_neon;
+    }
+    aom_dc_128_predictor_32x16 = aom_dc_128_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_32x16 = aom_dc_128_predictor_32x16_neon;
+    }
     aom_dc_128_predictor_32x32 = aom_dc_128_predictor_32x32_c;
     if (flags & HAS_NEON) aom_dc_128_predictor_32x32 = aom_dc_128_predictor_32x32_neon;
+    aom_dc_128_predictor_32x64 = aom_dc_128_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_32x64 = aom_dc_128_predictor_32x64_neon;
+    }
+    aom_dc_128_predictor_32x8 = aom_dc_128_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_32x8 = aom_dc_128_predictor_32x8_neon;
+    }
+    aom_dc_128_predictor_4x16 = aom_dc_128_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_4x16 = aom_dc_128_predictor_4x16_neon;
+    }
     aom_dc_128_predictor_4x4 = aom_dc_128_predictor_4x4_c;
     if (flags & HAS_NEON) aom_dc_128_predictor_4x4 = aom_dc_128_predictor_4x4_neon;
+    aom_dc_128_predictor_4x8 = aom_dc_128_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_4x8 = aom_dc_128_predictor_4x8_neon;
+    }
+    aom_dc_128_predictor_64x16 = aom_dc_128_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_64x16 = aom_dc_128_predictor_64x16_neon;
+    }
+    aom_dc_128_predictor_64x32 = aom_dc_128_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_64x32 = aom_dc_128_predictor_64x32_neon;
+    }
     aom_dc_128_predictor_64x64 = aom_dc_128_predictor_64x64_c;
     if (flags & HAS_NEON) {
       aom_dc_128_predictor_64x64 = aom_dc_128_predictor_64x64_neon;
     }
+    aom_dc_128_predictor_8x16 = aom_dc_128_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_8x16 = aom_dc_128_predictor_8x16_neon;
+    }
+    aom_dc_128_predictor_8x32 = aom_dc_128_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_8x32 = aom_dc_128_predictor_8x32_neon;
+    }
+    aom_dc_128_predictor_8x4 = aom_dc_128_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_128_predictor_8x4 = aom_dc_128_predictor_8x4_neon;
+    }
     aom_dc_128_predictor_8x8 = aom_dc_128_predictor_8x8_c;
     if (flags & HAS_NEON) aom_dc_128_predictor_8x8 = aom_dc_128_predictor_8x8_neon;
     aom_dc_left_predictor_16x16 = aom_dc_left_predictor_16x16_c;
     if (flags & HAS_NEON) aom_dc_left_predictor_16x16 = aom_dc_left_predictor_16x16_neon;
+    aom_dc_left_predictor_16x32 = aom_dc_left_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_16x32 = aom_dc_left_predictor_16x32_neon;
+    }
+    aom_dc_left_predictor_16x4 = aom_dc_left_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_16x4 = aom_dc_left_predictor_16x4_neon;
+    }
+    aom_dc_left_predictor_16x64 = aom_dc_left_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_16x64 = aom_dc_left_predictor_16x64_neon;
+    }
+    aom_dc_left_predictor_16x8 = aom_dc_left_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_16x8 = aom_dc_left_predictor_16x8_neon;
+    }
+    aom_dc_left_predictor_32x16 = aom_dc_left_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_32x16 = aom_dc_left_predictor_32x16_neon;
+    }
     aom_dc_left_predictor_32x32 = aom_dc_left_predictor_32x32_c;
     if (flags & HAS_NEON) aom_dc_left_predictor_32x32 = aom_dc_left_predictor_32x32_neon;
+    aom_dc_left_predictor_32x64 = aom_dc_left_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_32x64 = aom_dc_left_predictor_32x64_neon;
+    }
+    aom_dc_left_predictor_32x8 = aom_dc_left_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_32x8 = aom_dc_left_predictor_32x8_neon;
+    }
+    aom_dc_left_predictor_4x16 = aom_dc_left_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_4x16 = aom_dc_left_predictor_4x16_neon;
+    }
     aom_dc_left_predictor_4x4 = aom_dc_left_predictor_4x4_c;
     if (flags & HAS_NEON) aom_dc_left_predictor_4x4 = aom_dc_left_predictor_4x4_neon;
+    aom_dc_left_predictor_4x8 = aom_dc_left_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_4x8 = aom_dc_left_predictor_4x8_neon;
+    }
+    aom_dc_left_predictor_64x16 = aom_dc_left_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_64x16 = aom_dc_left_predictor_64x16_neon;
+    }
+    aom_dc_left_predictor_64x32 = aom_dc_left_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_64x32 = aom_dc_left_predictor_64x32_neon;
+    }
     aom_dc_left_predictor_64x64 = aom_dc_left_predictor_64x64_c;
     if (flags & HAS_NEON) {
       aom_dc_left_predictor_64x64 = aom_dc_left_predictor_64x64_neon;
     }
+    aom_dc_left_predictor_8x16 = aom_dc_left_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_8x16 = aom_dc_left_predictor_8x16_neon;
+    }
+    aom_dc_left_predictor_8x32 = aom_dc_left_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_8x32 = aom_dc_left_predictor_8x32_neon;
+    }
+    aom_dc_left_predictor_8x4 = aom_dc_left_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_left_predictor_8x4 = aom_dc_left_predictor_8x4_neon;
+    }
     aom_dc_left_predictor_8x8 = aom_dc_left_predictor_8x8_c;
     if (flags & HAS_NEON) aom_dc_left_predictor_8x8 = aom_dc_left_predictor_8x8_neon;
     aom_dc_predictor_16x16 = aom_dc_predictor_16x16_c;
     if (flags & HAS_NEON) aom_dc_predictor_16x16 = aom_dc_predictor_16x16_neon;
+    aom_dc_predictor_16x32 = aom_dc_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_16x32 = aom_dc_predictor_16x32_neon;
+    }
+    aom_dc_predictor_16x4 = aom_dc_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_16x4 = aom_dc_predictor_16x4_neon;
+    }
+    aom_dc_predictor_16x64 = aom_dc_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_16x64 = aom_dc_predictor_16x64_neon;
+    }
+    aom_dc_predictor_16x8 = aom_dc_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_16x8 = aom_dc_predictor_16x8_neon;
+    }
+    aom_dc_predictor_32x16 = aom_dc_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_32x16 = aom_dc_predictor_32x16_neon;
+    }
     aom_dc_predictor_32x32 = aom_dc_predictor_32x32_c;
     if (flags & HAS_NEON) aom_dc_predictor_32x32 = aom_dc_predictor_32x32_neon;
+    aom_dc_predictor_32x64 = aom_dc_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_32x64 = aom_dc_predictor_32x64_neon;
+    }
+    aom_dc_predictor_32x8 = aom_dc_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_32x8 = aom_dc_predictor_32x8_neon;
+    }
+    aom_dc_predictor_4x16 = aom_dc_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_4x16 = aom_dc_predictor_4x16_neon;
+    }
     aom_dc_predictor_4x4 = aom_dc_predictor_4x4_c;
     if (flags & HAS_NEON) aom_dc_predictor_4x4 = aom_dc_predictor_4x4_neon;
+    aom_dc_predictor_4x8 = aom_dc_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_4x8 = aom_dc_predictor_4x8_neon;
+    }
+    aom_dc_predictor_64x16 = aom_dc_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_64x16 = aom_dc_predictor_64x16_neon;
+    }
+    aom_dc_predictor_64x32 = aom_dc_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_64x32 = aom_dc_predictor_64x32_neon;
+    }
     aom_dc_predictor_64x64 = aom_dc_predictor_64x64_c;
     if (flags & HAS_NEON) {
       aom_dc_predictor_64x64 = aom_dc_predictor_64x64_neon;
     }
+    aom_dc_predictor_8x16 = aom_dc_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_8x16 = aom_dc_predictor_8x16_neon;
+    }
+    aom_dc_predictor_8x32 = aom_dc_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_8x32 = aom_dc_predictor_8x32_neon;
+    }
+    aom_dc_predictor_8x4 = aom_dc_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_predictor_8x4 = aom_dc_predictor_8x4_neon;
+    }
     aom_dc_predictor_8x8 = aom_dc_predictor_8x8_c;
     if (flags & HAS_NEON) aom_dc_predictor_8x8 = aom_dc_predictor_8x8_neon;
     aom_dc_top_predictor_16x16 = aom_dc_top_predictor_16x16_c;
     if (flags & HAS_NEON) aom_dc_top_predictor_16x16 = aom_dc_top_predictor_16x16_neon;
+    aom_dc_top_predictor_16x32 = aom_dc_top_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_16x32 = aom_dc_top_predictor_16x32_neon;
+    }
+    aom_dc_top_predictor_16x4 = aom_dc_top_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_16x4 = aom_dc_top_predictor_16x4_neon;
+    }
+    aom_dc_top_predictor_16x64 = aom_dc_top_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_16x64 = aom_dc_top_predictor_16x64_neon;
+    }
+    aom_dc_top_predictor_16x8 = aom_dc_top_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_16x8 = aom_dc_top_predictor_16x8_neon;
+    }
+    aom_dc_top_predictor_32x16 = aom_dc_top_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_32x16 = aom_dc_top_predictor_32x16_neon;
+    }
     aom_dc_top_predictor_32x32 = aom_dc_top_predictor_32x32_c;
     if (flags & HAS_NEON) aom_dc_top_predictor_32x32 = aom_dc_top_predictor_32x32_neon;
+    aom_dc_top_predictor_32x64 = aom_dc_top_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_32x64 = aom_dc_top_predictor_32x64_neon;
+    }
+    aom_dc_top_predictor_32x8 = aom_dc_top_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_32x8 = aom_dc_top_predictor_32x8_neon;
+    }
+    aom_dc_top_predictor_4x16 = aom_dc_top_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_4x16 = aom_dc_top_predictor_4x16_neon;
+    }
     aom_dc_top_predictor_4x4 = aom_dc_top_predictor_4x4_c;
     if (flags & HAS_NEON) aom_dc_top_predictor_4x4 = aom_dc_top_predictor_4x4_neon;
+    aom_dc_top_predictor_4x8 = aom_dc_top_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_4x8 = aom_dc_top_predictor_4x8_neon;
+    }
+    aom_dc_top_predictor_64x16 = aom_dc_top_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_64x16 = aom_dc_top_predictor_64x16_neon;
+    }
+    aom_dc_top_predictor_64x32 = aom_dc_top_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_64x32 = aom_dc_top_predictor_64x32_neon;
+    }
     aom_dc_top_predictor_64x64 = aom_dc_top_predictor_64x64_c;
     if (flags & HAS_NEON) {
       aom_dc_top_predictor_64x64 = aom_dc_top_predictor_64x64_neon;
     }
+    aom_dc_top_predictor_8x16 = aom_dc_top_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_8x16 = aom_dc_top_predictor_8x16_neon;
+    }
+    aom_dc_top_predictor_8x32 = aom_dc_top_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_8x32 = aom_dc_top_predictor_8x32_neon;
+    }
+    aom_dc_top_predictor_8x4 = aom_dc_top_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_dc_top_predictor_8x4 = aom_dc_top_predictor_8x4_neon;
+    }
     aom_dc_top_predictor_8x8 = aom_dc_top_predictor_8x8_c;
     if (flags & HAS_NEON) aom_dc_top_predictor_8x8 = aom_dc_top_predictor_8x8_neon;
     aom_fdct4x4 = aom_fdct4x4_c;
@@ -2013,10 +3167,70 @@
     if (flags & HAS_NEON) aom_get_var_sse_sum_8x8_quad = aom_get_var_sse_sum_8x8_quad_neon;
     aom_h_predictor_16x16 = aom_h_predictor_16x16_c;
     if (flags & HAS_NEON) aom_h_predictor_16x16 = aom_h_predictor_16x16_neon;
+    aom_h_predictor_16x32 = aom_h_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_16x32 = aom_h_predictor_16x32_neon;
+    }
+    aom_h_predictor_16x4 = aom_h_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_16x4 = aom_h_predictor_16x4_neon;
+    }
+    aom_h_predictor_16x64 = aom_h_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_16x64 = aom_h_predictor_16x64_neon;
+    }
+    aom_h_predictor_16x8 = aom_h_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_16x8 = aom_h_predictor_16x8_neon;
+    }
+    aom_h_predictor_32x16 = aom_h_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_32x16 = aom_h_predictor_32x16_neon;
+    }
     aom_h_predictor_32x32 = aom_h_predictor_32x32_c;
     if (flags & HAS_NEON) aom_h_predictor_32x32 = aom_h_predictor_32x32_neon;
+    aom_h_predictor_32x64 = aom_h_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_32x64 = aom_h_predictor_32x64_neon;
+    }
+    aom_h_predictor_32x8 = aom_h_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_32x8 = aom_h_predictor_32x8_neon;
+    }
+    aom_h_predictor_4x16 = aom_h_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_4x16 = aom_h_predictor_4x16_neon;
+    }
     aom_h_predictor_4x4 = aom_h_predictor_4x4_c;
     if (flags & HAS_NEON) aom_h_predictor_4x4 = aom_h_predictor_4x4_neon;
+    aom_h_predictor_4x8 = aom_h_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_4x8 = aom_h_predictor_4x8_neon;
+    }
+    aom_h_predictor_64x16 = aom_h_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_64x16 = aom_h_predictor_64x16_neon;
+    }
+    aom_h_predictor_64x32 = aom_h_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_64x32 = aom_h_predictor_64x32_neon;
+    }
+    aom_h_predictor_64x64 = aom_h_predictor_64x64_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_64x64 = aom_h_predictor_64x64_neon;
+    }
+    aom_h_predictor_8x16 = aom_h_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_8x16 = aom_h_predictor_8x16_neon;
+    }
+    aom_h_predictor_8x32 = aom_h_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_8x32 = aom_h_predictor_8x32_neon;
+    }
+    aom_h_predictor_8x4 = aom_h_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_h_predictor_8x4 = aom_h_predictor_8x4_neon;
+    }
     aom_h_predictor_8x8 = aom_h_predictor_8x8_c;
     if (flags & HAS_NEON) aom_h_predictor_8x8 = aom_h_predictor_8x8_neon;
     aom_hadamard_16x16 = aom_hadamard_16x16_c;
@@ -2119,6 +3333,83 @@
     if (flags & HAS_NEON) aom_masked_sad8x4 = aom_masked_sad8x4_neon;
     aom_masked_sad8x8 = aom_masked_sad8x8_c;
     if (flags & HAS_NEON) aom_masked_sad8x8 = aom_masked_sad8x8_neon;
+    aom_masked_sub_pixel_variance128x128 =
+        aom_masked_sub_pixel_variance128x128_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance128x128 =
+          aom_masked_sub_pixel_variance128x128_neon;
+    }
+    aom_masked_sub_pixel_variance128x64 = aom_masked_sub_pixel_variance128x64_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance128x64 =
+          aom_masked_sub_pixel_variance128x64_neon;
+    }
+    aom_masked_sub_pixel_variance16x16 = aom_masked_sub_pixel_variance16x16_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance16x16 =
+          aom_masked_sub_pixel_variance16x16_neon;
+    }
+    aom_masked_sub_pixel_variance16x32 = aom_masked_sub_pixel_variance16x32_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance16x32 =
+          aom_masked_sub_pixel_variance16x32_neon;
+    }
+    aom_masked_sub_pixel_variance16x8 = aom_masked_sub_pixel_variance16x8_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance16x8 =
+          aom_masked_sub_pixel_variance16x8_neon;
+    }
+    aom_masked_sub_pixel_variance32x16 = aom_masked_sub_pixel_variance32x16_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance32x16 =
+          aom_masked_sub_pixel_variance32x16_neon;
+    }
+    aom_masked_sub_pixel_variance32x32 = aom_masked_sub_pixel_variance32x32_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance32x32 =
+          aom_masked_sub_pixel_variance32x32_neon;
+    }
+    aom_masked_sub_pixel_variance32x64 = aom_masked_sub_pixel_variance32x64_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance32x64 =
+          aom_masked_sub_pixel_variance32x64_neon;
+    }
+    aom_masked_sub_pixel_variance4x4 = aom_masked_sub_pixel_variance4x4_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance4x4 = aom_masked_sub_pixel_variance4x4_neon;
+    }
+    aom_masked_sub_pixel_variance4x8 = aom_masked_sub_pixel_variance4x8_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance4x8 = aom_masked_sub_pixel_variance4x8_neon;
+    }
+    aom_masked_sub_pixel_variance64x128 = aom_masked_sub_pixel_variance64x128_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance64x128 =
+          aom_masked_sub_pixel_variance64x128_neon;
+    }
+    aom_masked_sub_pixel_variance64x32 = aom_masked_sub_pixel_variance64x32_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance64x32 =
+          aom_masked_sub_pixel_variance64x32_neon;
+    }
+    aom_masked_sub_pixel_variance64x64 = aom_masked_sub_pixel_variance64x64_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance64x64 =
+          aom_masked_sub_pixel_variance64x64_neon;
+    }
+    aom_masked_sub_pixel_variance8x16 = aom_masked_sub_pixel_variance8x16_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance8x16 =
+          aom_masked_sub_pixel_variance8x16_neon;
+    }
+    aom_masked_sub_pixel_variance8x4 = aom_masked_sub_pixel_variance8x4_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance8x4 = aom_masked_sub_pixel_variance8x4_neon;
+    }
+    aom_masked_sub_pixel_variance8x8 = aom_masked_sub_pixel_variance8x8_c;
+    if (flags & HAS_NEON) {
+      aom_masked_sub_pixel_variance8x8 = aom_masked_sub_pixel_variance8x8_neon;
+    }
     aom_minmax_8x8 = aom_minmax_8x8_c;
     if (flags & HAS_NEON) {
       aom_minmax_8x8 = aom_minmax_8x8_neon;
@@ -2523,10 +3814,70 @@
     if (flags & HAS_NEON) aom_sum_sse_2d_i16 = aom_sum_sse_2d_i16_neon;
     aom_v_predictor_16x16 = aom_v_predictor_16x16_c;
     if (flags & HAS_NEON) aom_v_predictor_16x16 = aom_v_predictor_16x16_neon;
+    aom_v_predictor_16x32 = aom_v_predictor_16x32_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_16x32 = aom_v_predictor_16x32_neon;
+    }
+    aom_v_predictor_16x4 = aom_v_predictor_16x4_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_16x4 = aom_v_predictor_16x4_neon;
+    }
+    aom_v_predictor_16x64 = aom_v_predictor_16x64_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_16x64 = aom_v_predictor_16x64_neon;
+    }
+    aom_v_predictor_16x8 = aom_v_predictor_16x8_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_16x8 = aom_v_predictor_16x8_neon;
+    }
+    aom_v_predictor_32x16 = aom_v_predictor_32x16_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_32x16 = aom_v_predictor_32x16_neon;
+    }
     aom_v_predictor_32x32 = aom_v_predictor_32x32_c;
     if (flags & HAS_NEON) aom_v_predictor_32x32 = aom_v_predictor_32x32_neon;
+    aom_v_predictor_32x64 = aom_v_predictor_32x64_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_32x64 = aom_v_predictor_32x64_neon;
+    }
+    aom_v_predictor_32x8 = aom_v_predictor_32x8_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_32x8 = aom_v_predictor_32x8_neon;
+    }
+    aom_v_predictor_4x16 = aom_v_predictor_4x16_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_4x16 = aom_v_predictor_4x16_neon;
+    }
     aom_v_predictor_4x4 = aom_v_predictor_4x4_c;
     if (flags & HAS_NEON) aom_v_predictor_4x4 = aom_v_predictor_4x4_neon;
+    aom_v_predictor_4x8 = aom_v_predictor_4x8_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_4x8 = aom_v_predictor_4x8_neon;
+    }
+    aom_v_predictor_64x16 = aom_v_predictor_64x16_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_64x16 = aom_v_predictor_64x16_neon;
+    }
+    aom_v_predictor_64x32 = aom_v_predictor_64x32_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_64x32 = aom_v_predictor_64x32_neon;
+    }
+    aom_v_predictor_64x64 = aom_v_predictor_64x64_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_64x64 = aom_v_predictor_64x64_neon;
+    }
+    aom_v_predictor_8x16 = aom_v_predictor_8x16_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_8x16 = aom_v_predictor_8x16_neon;
+    }
+    aom_v_predictor_8x32 = aom_v_predictor_8x32_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_8x32 = aom_v_predictor_8x32_neon;
+    }
+    aom_v_predictor_8x4 = aom_v_predictor_8x4_c;
+    if (flags & HAS_NEON) {
+      aom_v_predictor_8x4 = aom_v_predictor_8x4_neon;
+    }
     aom_v_predictor_8x8 = aom_v_predictor_8x8_c;
     if (flags & HAS_NEON) aom_v_predictor_8x8 = aom_v_predictor_8x8_neon;
     aom_variance128x128 = aom_variance128x128_c;
diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
index 37a8f71..8807417b 100644
--- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/av1_rtcd.h
@@ -127,10 +127,32 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+RTCD_EXTERN void (*av1_calc_indices_dim1)(const int16_t* data,
+                                          const int16_t* centroids,
+                                          uint8_t* indices,
+                                          int64_t* total_dist,
+                                          int n,
+                                          int k);
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+RTCD_EXTERN void (*av1_calc_indices_dim2)(const int16_t* data,
+                                          const int16_t* centroids,
+                                          uint8_t* indices,
+                                          int64_t* total_dist,
+                                          int n,
+                                          int k);
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
@@ -586,6 +608,14 @@
     if (flags & HAS_NEON) av1_block_error_lp = av1_block_error_lp_neon;
     av1_build_compound_diffwtd_mask_d16 = av1_build_compound_diffwtd_mask_d16_c;
     if (flags & HAS_NEON) av1_build_compound_diffwtd_mask_d16 = av1_build_compound_diffwtd_mask_d16_neon;
+    av1_calc_indices_dim1 = av1_calc_indices_dim1_c;
+    if (flags & HAS_NEON) {
+      av1_calc_indices_dim1 = av1_calc_indices_dim1_neon;
+    }
+    av1_calc_indices_dim2 = av1_calc_indices_dim2_c;
+    if (flags & HAS_NEON) {
+      av1_calc_indices_dim2 = av1_calc_indices_dim2_neon;
+    }
     av1_convolve_2d_sr = av1_convolve_2d_sr_c;
     if (flags & HAS_NEON) av1_convolve_2d_sr = av1_convolve_2d_sr_neon;
     av1_convolve_x_sr = av1_convolve_x_sr_c;
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
index 56f39b6..0dcda7b 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
index ad39421..8afb854d 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
index cc9741db..1db5fff 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_dsp_rtcd.h
@@ -54,7 +54,16 @@
 #define aom_comp_avg_pred aom_comp_avg_pred_neon
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+#define aom_comp_mask_pred aom_comp_mask_pred_neon
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -74,45 +83,89 @@
 #define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_neon
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_neon
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_neon
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_neon
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_neon
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_neon
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_neon
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_neon
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_neon
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_neon
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_neon
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -122,13 +175,25 @@
 #define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_neon
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_neon
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_neon
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_neon
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -139,45 +204,89 @@
 #define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_neon
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_neon
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_neon
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_neon
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_neon
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_neon
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_neon
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_neon
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_neon
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_neon
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_neon
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -187,13 +296,25 @@
 #define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_neon
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_neon
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_neon
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_neon
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -204,45 +325,89 @@
 #define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_neon
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_neon
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_neon
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_neon
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_neon
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_neon
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_neon
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_neon
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_neon
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_neon
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_neon
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -252,13 +417,25 @@
 #define aom_dc_predictor_64x64 aom_dc_predictor_64x64_neon
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_neon
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_neon
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_neon
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -269,45 +446,89 @@
 #define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_neon
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_neon
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_neon
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_neon
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_neon
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_neon
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_neon
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_neon
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_neon
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_neon
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_neon
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -317,13 +538,25 @@
 #define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_neon
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_neon
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_neon
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_neon
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -470,57 +703,117 @@
 #define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_neon
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_neon
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_neon
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_neon
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_neon
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_neon
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_neon
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_neon
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_neon
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_neon
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_neon
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_neon
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_neon
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_neon
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_neon
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -790,52 +1083,241 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x128 \
+  aom_masked_sub_pixel_variance128x128_neon
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x64 \
+  aom_masked_sub_pixel_variance128x64_neon
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x16 \
+  aom_masked_sub_pixel_variance16x16_neon
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x32 \
+  aom_masked_sub_pixel_variance16x32_neon
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_neon
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x16 \
+  aom_masked_sub_pixel_variance32x16_neon
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x32 \
+  aom_masked_sub_pixel_variance32x32_neon
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x64 \
+  aom_masked_sub_pixel_variance32x64_neon
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_neon
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_neon
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x128 \
+  aom_masked_sub_pixel_variance64x128_neon
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x32 \
+  aom_masked_sub_pixel_variance64x32_neon
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x64 \
+  aom_masked_sub_pixel_variance64x64_neon
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_neon
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_neon
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_neon
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -972,9 +1454,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_neon
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_neon
@@ -990,9 +1469,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_neon
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_neon
@@ -1008,9 +1484,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_neon
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_neon
@@ -1026,9 +1499,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_neon
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_neon
@@ -1044,9 +1514,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_neon
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_neon
@@ -1062,9 +1529,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_neon
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_neon
@@ -1080,9 +1544,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_neon
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_neon
@@ -1098,9 +1559,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_neon
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_neon
@@ -1116,9 +1574,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_neon
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_neon
@@ -1134,9 +1589,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_neon
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_neon
@@ -1152,9 +1604,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_neon
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_neon
@@ -1170,9 +1619,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_neon
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_neon
@@ -1188,9 +1634,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_neon
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_neon
@@ -1206,9 +1649,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_neon
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_neon
@@ -1224,9 +1664,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_neon
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_neon
@@ -1242,9 +1679,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_neon
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_neon
@@ -1764,57 +2198,117 @@
 #define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_neon
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_neon
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_neon
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_neon
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_neon
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_neon
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_neon
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_neon
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_neon
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_neon
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_neon
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_neon
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_neon
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_neon
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_neon
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
diff --git a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
index 6dfd871..99a0c0a 100644
--- a/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm-neon/config/av1_rtcd.h
@@ -127,10 +127,22 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim1 av1_calc_indices_dim1_neon
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim2 av1_calc_indices_dim2_neon
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.asm b/third_party/libaom/source/config/linux/arm/config/aom_config.asm
index 08fd36d..7326d71 100644
--- a/third_party/libaom/source/config/linux/arm/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/arm/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.h b/third_party/libaom/source/config/linux/arm/config/aom_config.h
index edc8d5b..6c35dcf1 100644
--- a/third_party/libaom/source/config/linux/arm/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/arm/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/arm/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm/config/aom_dsp_rtcd.h
index 8eb32b8..7fc9c761 100644
--- a/third_party/libaom/source/config/linux/arm/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm/config/aom_dsp_rtcd.h
@@ -834,9 +834,6 @@
 void aom_sad128x128x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_c
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_c
 
@@ -849,9 +846,6 @@
 void aom_sad128x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_c
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_c
 
@@ -864,9 +858,6 @@
 void aom_sad16x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_c
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_c
 
@@ -879,9 +870,6 @@
 void aom_sad16x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_c
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_c
 
@@ -894,9 +882,6 @@
 void aom_sad16x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_c
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_c
 
@@ -909,9 +894,6 @@
 void aom_sad32x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_c
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_c
 
@@ -924,9 +906,6 @@
 void aom_sad32x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_c
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_c
 
@@ -939,9 +918,6 @@
 void aom_sad32x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_c
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_c
 
@@ -954,9 +930,6 @@
 void aom_sad4x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_c
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_c
 
@@ -969,9 +942,6 @@
 void aom_sad4x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_c
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_c
 
@@ -984,9 +954,6 @@
 void aom_sad64x128x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_c
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_c
 
@@ -999,9 +966,6 @@
 void aom_sad64x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_c
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_c
 
@@ -1014,9 +978,6 @@
 void aom_sad64x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_c
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_c
 
@@ -1029,9 +990,6 @@
 void aom_sad8x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_c
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_c
 
@@ -1044,9 +1002,6 @@
 void aom_sad8x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_c
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_c
 
@@ -1059,9 +1014,6 @@
 void aom_sad8x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_c
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_c
 
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
index 56f39b6..0dcda7b 100644
--- a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.h b/third_party/libaom/source/config/linux/arm64/config/aom_config.h
index ad39421..8afb854d 100644
--- a/third_party/libaom/source/config/linux/arm64/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/arm64/config/aom_dsp_rtcd.h
index cc9741db..1db5fff 100644
--- a/third_party/libaom/source/config/linux/arm64/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm64/config/aom_dsp_rtcd.h
@@ -54,7 +54,16 @@
 #define aom_comp_avg_pred aom_comp_avg_pred_neon
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+#define aom_comp_mask_pred aom_comp_mask_pred_neon
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -74,45 +83,89 @@
 #define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_neon
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_neon
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_neon
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_neon
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_neon
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_neon
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_neon
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_neon
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_neon
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_neon
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_neon
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -122,13 +175,25 @@
 #define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_neon
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_neon
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_neon
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_neon
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -139,45 +204,89 @@
 #define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_neon
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_neon
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_neon
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_neon
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_neon
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_neon
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_neon
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_neon
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_neon
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_neon
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_neon
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -187,13 +296,25 @@
 #define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_neon
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_neon
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_neon
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_neon
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -204,45 +325,89 @@
 #define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_neon
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_neon
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_neon
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_neon
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_neon
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_neon
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_neon
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_neon
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_neon
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_neon
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_neon
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -252,13 +417,25 @@
 #define aom_dc_predictor_64x64 aom_dc_predictor_64x64_neon
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_neon
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_neon
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_neon
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -269,45 +446,89 @@
 #define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_neon
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_neon
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_neon
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_neon
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_neon
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_neon
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_neon
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_neon
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_neon
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_neon
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_neon
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -317,13 +538,25 @@
 #define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_neon
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_neon
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_neon
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_neon
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -470,57 +703,117 @@
 #define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_neon
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_neon
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_neon
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_neon
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_neon
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_neon
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_neon
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_neon
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_neon
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_neon
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_neon
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_neon
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_neon
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_neon
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_neon
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -790,52 +1083,241 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x128 \
+  aom_masked_sub_pixel_variance128x128_neon
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x64 \
+  aom_masked_sub_pixel_variance128x64_neon
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x16 \
+  aom_masked_sub_pixel_variance16x16_neon
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x32 \
+  aom_masked_sub_pixel_variance16x32_neon
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_neon
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x16 \
+  aom_masked_sub_pixel_variance32x16_neon
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x32 \
+  aom_masked_sub_pixel_variance32x32_neon
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x64 \
+  aom_masked_sub_pixel_variance32x64_neon
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_neon
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_neon
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x128 \
+  aom_masked_sub_pixel_variance64x128_neon
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x32 \
+  aom_masked_sub_pixel_variance64x32_neon
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x64 \
+  aom_masked_sub_pixel_variance64x64_neon
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_neon
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_neon
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_neon
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -972,9 +1454,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_neon
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_neon
@@ -990,9 +1469,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_neon
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_neon
@@ -1008,9 +1484,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_neon
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_neon
@@ -1026,9 +1499,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_neon
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_neon
@@ -1044,9 +1514,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_neon
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_neon
@@ -1062,9 +1529,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_neon
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_neon
@@ -1080,9 +1544,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_neon
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_neon
@@ -1098,9 +1559,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_neon
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_neon
@@ -1116,9 +1574,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_neon
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_neon
@@ -1134,9 +1589,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_neon
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_neon
@@ -1152,9 +1604,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_neon
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_neon
@@ -1170,9 +1619,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_neon
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_neon
@@ -1188,9 +1634,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_neon
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_neon
@@ -1206,9 +1649,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_neon
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_neon
@@ -1224,9 +1664,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_neon
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_neon
@@ -1242,9 +1679,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_neon
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_neon
@@ -1764,57 +2198,117 @@
 #define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_neon
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_neon
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_neon
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_neon
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_neon
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_neon
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_neon
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_neon
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_neon
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_neon
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_neon
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_neon
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_neon
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_neon
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_neon
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
diff --git a/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h
index 6dfd871..99a0c0a 100644
--- a/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/linux/arm64/config/av1_rtcd.h
@@ -127,10 +127,22 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim1 av1_calc_indices_dim1_neon
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim2 av1_calc_indices_dim2_neon
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.asm b/third_party/libaom/source/config/linux/generic/config/aom_config.asm
index c21e16c6..19c6397 100644
--- a/third_party/libaom/source/config/linux/generic/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/generic/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.h b/third_party/libaom/source/config/linux/generic/config/aom_config.h
index e63e6df4b..134f606 100644
--- a/third_party/libaom/source/config/linux/generic/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/generic/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/generic/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/generic/config/aom_dsp_rtcd.h
index 109eda4..b911a0c 100644
--- a/third_party/libaom/source/config/linux/generic/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/generic/config/aom_dsp_rtcd.h
@@ -834,9 +834,6 @@
 void aom_sad128x128x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_c
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_c
 
@@ -849,9 +846,6 @@
 void aom_sad128x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_c
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_c
 
@@ -864,9 +858,6 @@
 void aom_sad16x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_c
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_c
 
@@ -879,9 +870,6 @@
 void aom_sad16x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_c
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_c
 
@@ -894,9 +882,6 @@
 void aom_sad16x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_c
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_c
 
@@ -909,9 +894,6 @@
 void aom_sad32x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_c
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_c
 
@@ -924,9 +906,6 @@
 void aom_sad32x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_c
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_c
 
@@ -939,9 +918,6 @@
 void aom_sad32x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_c
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_c
 
@@ -954,9 +930,6 @@
 void aom_sad4x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_c
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_c
 
@@ -969,9 +942,6 @@
 void aom_sad4x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_c
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_c
 
@@ -984,9 +954,6 @@
 void aom_sad64x128x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_c
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_c
 
@@ -999,9 +966,6 @@
 void aom_sad64x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_c
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_c
 
@@ -1014,9 +978,6 @@
 void aom_sad64x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_c
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_c
 
@@ -1029,9 +990,6 @@
 void aom_sad8x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_c
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_c
 
@@ -1044,9 +1002,6 @@
 void aom_sad8x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_c
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_c
 
@@ -1059,9 +1014,6 @@
 void aom_sad8x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_c
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_c
 
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_config.asm b/third_party/libaom/source/config/linux/ia32/config/aom_config.asm
index facbf54e..e466e0e 100644
--- a/third_party/libaom/source/config/linux/ia32/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/ia32/config/aom_config.asm
@@ -16,6 +16,7 @@
 %define CONFIG_COLLECT_COMPONENT_TIMING 0
 %define CONFIG_COLLECT_PARTITION_STATS 0
 %define CONFIG_COLLECT_RD_STATS 0
+%define CONFIG_CWG_C013 0
 %define CONFIG_DEBUG 0
 %define CONFIG_DENOISE 1
 %define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_config.h b/third_party/libaom/source/config/linux/ia32/config/aom_config.h
index 1871f102..8673a23 100644
--- a/third_party/libaom/source/config/linux/ia32/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/ia32/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/ia32/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/ia32/config/aom_dsp_rtcd.h
index 56fb931..d6d92891 100644
--- a/third_party/libaom/source/config/linux/ia32/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/ia32/config/aom_dsp_rtcd.h
@@ -1287,9 +1287,6 @@
 void aom_sad128x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1309,9 +1306,6 @@
 void aom_sad128x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_sse2
@@ -1329,9 +1323,6 @@
 void aom_sad16x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_sse2
@@ -1349,9 +1340,6 @@
 void aom_sad16x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_sse2
@@ -1369,9 +1357,6 @@
 void aom_sad16x8x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1391,9 +1376,6 @@
 void aom_sad32x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1413,9 +1395,6 @@
 void aom_sad32x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1435,9 +1414,6 @@
 void aom_sad32x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_sse2
@@ -1453,9 +1429,6 @@
 void aom_sad4x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_sse2
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_sse2
@@ -1471,9 +1444,6 @@
 void aom_sad4x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_sse2
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1493,9 +1463,6 @@
 void aom_sad64x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1515,9 +1482,6 @@
 void aom_sad64x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1537,9 +1501,6 @@
 void aom_sad64x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_sse2
@@ -1555,9 +1516,6 @@
 void aom_sad8x16x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_sse2
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_sse2
@@ -1573,9 +1531,6 @@
 void aom_sad8x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_sse2
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_sse2
@@ -1591,9 +1546,6 @@
 void aom_sad8x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_sse2
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.asm b/third_party/libaom/source/config/linux/x64/config/aom_config.asm
index 5b34c7d..1903836 100644
--- a/third_party/libaom/source/config/linux/x64/config/aom_config.asm
+++ b/third_party/libaom/source/config/linux/x64/config/aom_config.asm
@@ -16,6 +16,7 @@
 %define CONFIG_COLLECT_COMPONENT_TIMING 0
 %define CONFIG_COLLECT_PARTITION_STATS 0
 %define CONFIG_COLLECT_RD_STATS 0
+%define CONFIG_CWG_C013 0
 %define CONFIG_DEBUG 0
 %define CONFIG_DENOISE 1
 %define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.h b/third_party/libaom/source/config/linux/x64/config/aom_config.h
index ad1790e..e62ad8bd 100644
--- a/third_party/libaom/source/config/linux/x64/config/aom_config.h
+++ b/third_party/libaom/source/config/linux/x64/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/linux/x64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/linux/x64/config/aom_dsp_rtcd.h
index b98b07b..7c32033 100644
--- a/third_party/libaom/source/config/linux/x64/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/linux/x64/config/aom_dsp_rtcd.h
@@ -1289,9 +1289,6 @@
 void aom_sad128x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1311,9 +1308,6 @@
 void aom_sad128x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_sse2
@@ -1331,9 +1325,6 @@
 void aom_sad16x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_sse2
@@ -1351,9 +1342,6 @@
 void aom_sad16x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_sse2
@@ -1371,9 +1359,6 @@
 void aom_sad16x8x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1393,9 +1378,6 @@
 void aom_sad32x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1415,9 +1397,6 @@
 void aom_sad32x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1437,9 +1416,6 @@
 void aom_sad32x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_sse2
@@ -1455,9 +1431,6 @@
 void aom_sad4x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_sse2
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_sse2
@@ -1473,9 +1446,6 @@
 void aom_sad4x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_sse2
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1495,9 +1465,6 @@
 void aom_sad64x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1517,9 +1484,6 @@
 void aom_sad64x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1539,9 +1503,6 @@
 void aom_sad64x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_sse2
@@ -1557,9 +1518,6 @@
 void aom_sad8x16x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_sse2
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_sse2
@@ -1575,9 +1533,6 @@
 void aom_sad8x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_sse2
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_sse2
@@ -1593,9 +1548,6 @@
 void aom_sad8x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_sse2
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.asm b/third_party/libaom/source/config/win/arm64/config/aom_config.asm
index 56f39b6..0dcda7b 100644
--- a/third_party/libaom/source/config/win/arm64/config/aom_config.asm
+++ b/third_party/libaom/source/config/win/arm64/config/aom_config.asm
@@ -26,6 +26,7 @@
 CONFIG_COLLECT_COMPONENT_TIMING equ 0
 CONFIG_COLLECT_PARTITION_STATS equ 0
 CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_CWG_C013 equ 0
 CONFIG_DEBUG equ 0
 CONFIG_DENOISE equ 1
 CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.h b/third_party/libaom/source/config/win/arm64/config/aom_config.h
index 1e396d3..bceb338 100644
--- a/third_party/libaom/source/config/win/arm64/config/aom_config.h
+++ b/third_party/libaom/source/config/win/arm64/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h
index cc9741db..1db5fff 100644
--- a/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h
@@ -54,7 +54,16 @@
 #define aom_comp_avg_pred aom_comp_avg_pred_neon
 
 void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask);
-#define aom_comp_mask_pred aom_comp_mask_pred_c
+void aom_comp_mask_pred_neon(uint8_t* comp_pred,
+                             const uint8_t* pred,
+                             int width,
+                             int height,
+                             const uint8_t* ref,
+                             int ref_stride,
+                             const uint8_t* mask,
+                             int mask_stride,
+                             int invert_mask);
+#define aom_comp_mask_pred aom_comp_mask_pred_neon
 
 void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h);
 #define aom_convolve8 aom_convolve8_c
@@ -74,45 +83,89 @@
 #define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
 
 void aom_dc_128_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+void aom_dc_128_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_neon
 
 void aom_dc_128_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+void aom_dc_128_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_neon
 
 void aom_dc_128_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+void aom_dc_128_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_neon
 
 void aom_dc_128_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+void aom_dc_128_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_neon
 
 void aom_dc_128_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+void aom_dc_128_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_neon
 
 void aom_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
 
 void aom_dc_128_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+void aom_dc_128_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_neon
 
 void aom_dc_128_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+void aom_dc_128_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_neon
 
 void aom_dc_128_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+void aom_dc_128_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_neon
 
 void aom_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
 
 void aom_dc_128_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+void aom_dc_128_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_neon
 
 void aom_dc_128_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+void aom_dc_128_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_neon
 
 void aom_dc_128_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+void aom_dc_128_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_neon
 
 void aom_dc_128_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_64x64_neon(uint8_t* dst,
@@ -122,13 +175,25 @@
 #define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_neon
 
 void aom_dc_128_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+void aom_dc_128_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_neon
 
 void aom_dc_128_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+void aom_dc_128_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_neon
 
 void aom_dc_128_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+void aom_dc_128_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_neon
 
 void aom_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -139,45 +204,89 @@
 #define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
 
 void aom_dc_left_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+void aom_dc_left_predictor_16x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_neon
 
 void aom_dc_left_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+void aom_dc_left_predictor_16x4_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_neon
 
 void aom_dc_left_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+void aom_dc_left_predictor_16x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_neon
 
 void aom_dc_left_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+void aom_dc_left_predictor_16x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_neon
 
 void aom_dc_left_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+void aom_dc_left_predictor_32x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_neon
 
 void aom_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
 
 void aom_dc_left_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+void aom_dc_left_predictor_32x64_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_neon
 
 void aom_dc_left_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+void aom_dc_left_predictor_32x8_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_neon
 
 void aom_dc_left_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+void aom_dc_left_predictor_4x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_neon
 
 void aom_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
 
 void aom_dc_left_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+void aom_dc_left_predictor_4x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_neon
 
 void aom_dc_left_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+void aom_dc_left_predictor_64x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_neon
 
 void aom_dc_left_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+void aom_dc_left_predictor_64x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_neon
 
 void aom_dc_left_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_64x64_neon(uint8_t* dst,
@@ -187,13 +296,25 @@
 #define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_neon
 
 void aom_dc_left_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+void aom_dc_left_predictor_8x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_neon
 
 void aom_dc_left_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+void aom_dc_left_predictor_8x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_neon
 
 void aom_dc_left_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+void aom_dc_left_predictor_8x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_neon
 
 void aom_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -204,45 +325,89 @@
 #define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
 
 void aom_dc_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+void aom_dc_predictor_16x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_neon
 
 void aom_dc_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+void aom_dc_predictor_16x4_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_neon
 
 void aom_dc_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+void aom_dc_predictor_16x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_neon
 
 void aom_dc_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+void aom_dc_predictor_16x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_neon
 
 void aom_dc_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+void aom_dc_predictor_32x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_neon
 
 void aom_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
 
 void aom_dc_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+void aom_dc_predictor_32x64_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_neon
 
 void aom_dc_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+void aom_dc_predictor_32x8_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_neon
 
 void aom_dc_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+void aom_dc_predictor_4x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_neon
 
 void aom_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
 
 void aom_dc_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+void aom_dc_predictor_4x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_neon
 
 void aom_dc_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+void aom_dc_predictor_64x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_neon
 
 void aom_dc_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+void aom_dc_predictor_64x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_neon
 
 void aom_dc_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_64x64_neon(uint8_t* dst,
@@ -252,13 +417,25 @@
 #define aom_dc_predictor_64x64 aom_dc_predictor_64x64_neon
 
 void aom_dc_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+void aom_dc_predictor_8x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_neon
 
 void aom_dc_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+void aom_dc_predictor_8x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_neon
 
 void aom_dc_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+void aom_dc_predictor_8x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_neon
 
 void aom_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -269,45 +446,89 @@
 #define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
 
 void aom_dc_top_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+void aom_dc_top_predictor_16x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_neon
 
 void aom_dc_top_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+void aom_dc_top_predictor_16x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_neon
 
 void aom_dc_top_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+void aom_dc_top_predictor_16x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_neon
 
 void aom_dc_top_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+void aom_dc_top_predictor_16x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_neon
 
 void aom_dc_top_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+void aom_dc_top_predictor_32x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_neon
 
 void aom_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
 
 void aom_dc_top_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+void aom_dc_top_predictor_32x64_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_neon
 
 void aom_dc_top_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+void aom_dc_top_predictor_32x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_neon
 
 void aom_dc_top_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+void aom_dc_top_predictor_4x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_neon
 
 void aom_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
 
 void aom_dc_top_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+void aom_dc_top_predictor_4x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_neon
 
 void aom_dc_top_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+void aom_dc_top_predictor_64x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_neon
 
 void aom_dc_top_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+void aom_dc_top_predictor_64x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_neon
 
 void aom_dc_top_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_64x64_neon(uint8_t* dst,
@@ -317,13 +538,25 @@
 #define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_neon
 
 void aom_dc_top_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+void aom_dc_top_predictor_8x16_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_neon
 
 void aom_dc_top_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+void aom_dc_top_predictor_8x32_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_neon
 
 void aom_dc_top_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+void aom_dc_top_predictor_8x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_neon
 
 void aom_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -470,57 +703,117 @@
 #define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
 
 void aom_h_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+void aom_h_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_neon
 
 void aom_h_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+void aom_h_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_neon
 
 void aom_h_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+void aom_h_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_neon
 
 void aom_h_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+void aom_h_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_neon
 
 void aom_h_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+void aom_h_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_neon
 
 void aom_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
 
 void aom_h_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+void aom_h_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_neon
 
 void aom_h_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+void aom_h_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_neon
 
 void aom_h_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+void aom_h_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_neon
 
 void aom_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
 
 void aom_h_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+void aom_h_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_neon
 
 void aom_h_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+void aom_h_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_neon
 
 void aom_h_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+void aom_h_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_neon
 
 void aom_h_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+void aom_h_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_neon
 
 void aom_h_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+void aom_h_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_neon
 
 void aom_h_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+void aom_h_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_neon
 
 void aom_h_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+void aom_h_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_neon
 
 void aom_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
@@ -790,52 +1083,241 @@
 #define aom_masked_sad8x8x4d aom_masked_sad8x8x4d_c
 
 unsigned int aom_masked_sub_pixel_variance128x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x128 aom_masked_sub_pixel_variance128x128_c
+unsigned int aom_masked_sub_pixel_variance128x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x128 \
+  aom_masked_sub_pixel_variance128x128_neon
 
 unsigned int aom_masked_sub_pixel_variance128x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance128x64 aom_masked_sub_pixel_variance128x64_c
+unsigned int aom_masked_sub_pixel_variance128x64_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance128x64 \
+  aom_masked_sub_pixel_variance128x64_neon
 
 unsigned int aom_masked_sub_pixel_variance16x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x16 aom_masked_sub_pixel_variance16x16_c
+unsigned int aom_masked_sub_pixel_variance16x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x16 \
+  aom_masked_sub_pixel_variance16x16_neon
 
 unsigned int aom_masked_sub_pixel_variance16x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x32 aom_masked_sub_pixel_variance16x32_c
+unsigned int aom_masked_sub_pixel_variance16x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x32 \
+  aom_masked_sub_pixel_variance16x32_neon
 
 unsigned int aom_masked_sub_pixel_variance16x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_c
+unsigned int aom_masked_sub_pixel_variance16x8_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance16x8 aom_masked_sub_pixel_variance16x8_neon
 
 unsigned int aom_masked_sub_pixel_variance32x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x16 aom_masked_sub_pixel_variance32x16_c
+unsigned int aom_masked_sub_pixel_variance32x16_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x16 \
+  aom_masked_sub_pixel_variance32x16_neon
 
 unsigned int aom_masked_sub_pixel_variance32x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x32 aom_masked_sub_pixel_variance32x32_c
+unsigned int aom_masked_sub_pixel_variance32x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x32 \
+  aom_masked_sub_pixel_variance32x32_neon
 
 unsigned int aom_masked_sub_pixel_variance32x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance32x64 aom_masked_sub_pixel_variance32x64_c
+unsigned int aom_masked_sub_pixel_variance32x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance32x64 \
+  aom_masked_sub_pixel_variance32x64_neon
 
 unsigned int aom_masked_sub_pixel_variance4x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_c
+unsigned int aom_masked_sub_pixel_variance4x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x4 aom_masked_sub_pixel_variance4x4_neon
 
 unsigned int aom_masked_sub_pixel_variance4x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_c
+unsigned int aom_masked_sub_pixel_variance4x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance4x8 aom_masked_sub_pixel_variance4x8_neon
 
 unsigned int aom_masked_sub_pixel_variance64x128_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x128 aom_masked_sub_pixel_variance64x128_c
+unsigned int aom_masked_sub_pixel_variance64x128_neon(
+    const uint8_t* src,
+    int src_stride,
+    int xoffset,
+    int yoffset,
+    const uint8_t* ref,
+    int ref_stride,
+    const uint8_t* second_pred,
+    const uint8_t* msk,
+    int msk_stride,
+    int invert_mask,
+    unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x128 \
+  aom_masked_sub_pixel_variance64x128_neon
 
 unsigned int aom_masked_sub_pixel_variance64x32_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x32 aom_masked_sub_pixel_variance64x32_c
+unsigned int aom_masked_sub_pixel_variance64x32_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x32 \
+  aom_masked_sub_pixel_variance64x32_neon
 
 unsigned int aom_masked_sub_pixel_variance64x64_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance64x64 aom_masked_sub_pixel_variance64x64_c
+unsigned int aom_masked_sub_pixel_variance64x64_neon(const uint8_t* src,
+                                                     int src_stride,
+                                                     int xoffset,
+                                                     int yoffset,
+                                                     const uint8_t* ref,
+                                                     int ref_stride,
+                                                     const uint8_t* second_pred,
+                                                     const uint8_t* msk,
+                                                     int msk_stride,
+                                                     int invert_mask,
+                                                     unsigned int* sse);
+#define aom_masked_sub_pixel_variance64x64 \
+  aom_masked_sub_pixel_variance64x64_neon
 
 unsigned int aom_masked_sub_pixel_variance8x16_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_c
+unsigned int aom_masked_sub_pixel_variance8x16_neon(const uint8_t* src,
+                                                    int src_stride,
+                                                    int xoffset,
+                                                    int yoffset,
+                                                    const uint8_t* ref,
+                                                    int ref_stride,
+                                                    const uint8_t* second_pred,
+                                                    const uint8_t* msk,
+                                                    int msk_stride,
+                                                    int invert_mask,
+                                                    unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x16 aom_masked_sub_pixel_variance8x16_neon
 
 unsigned int aom_masked_sub_pixel_variance8x4_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_c
+unsigned int aom_masked_sub_pixel_variance8x4_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x4 aom_masked_sub_pixel_variance8x4_neon
 
 unsigned int aom_masked_sub_pixel_variance8x8_c(const uint8_t *src, int src_stride, int xoffset, int yoffset, const uint8_t *ref, int ref_stride, const uint8_t *second_pred, const uint8_t *msk, int msk_stride, int invert_mask, unsigned int *sse);
-#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_c
+unsigned int aom_masked_sub_pixel_variance8x8_neon(const uint8_t* src,
+                                                   int src_stride,
+                                                   int xoffset,
+                                                   int yoffset,
+                                                   const uint8_t* ref,
+                                                   int ref_stride,
+                                                   const uint8_t* second_pred,
+                                                   const uint8_t* msk,
+                                                   int msk_stride,
+                                                   int invert_mask,
+                                                   unsigned int* sse);
+#define aom_masked_sub_pixel_variance8x8 aom_masked_sub_pixel_variance8x8_neon
 
 void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max);
 void aom_minmax_8x8_neon(const uint8_t* s,
@@ -972,9 +1454,6 @@
 void aom_sad128x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x128x4d aom_sad128x128x4d_neon
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad128x64 aom_sad128x64_neon
@@ -990,9 +1469,6 @@
 void aom_sad128x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad128x64x4d aom_sad128x64x4d_neon
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_neon
@@ -1008,9 +1484,6 @@
 void aom_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x16x4d aom_sad16x16x4d_neon
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_neon
@@ -1026,9 +1499,6 @@
 void aom_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x32x4d aom_sad16x32x4d_neon
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_neon
@@ -1044,9 +1514,6 @@
 void aom_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad16x8x4d aom_sad16x8x4d_neon
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x16 aom_sad32x16_neon
@@ -1062,9 +1529,6 @@
 void aom_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x16x4d aom_sad32x16x4d_neon
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x32 aom_sad32x32_neon
@@ -1080,9 +1544,6 @@
 void aom_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x32x4d aom_sad32x32x4d_neon
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad32x64 aom_sad32x64_neon
@@ -1098,9 +1559,6 @@
 void aom_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad32x64x4d aom_sad32x64x4d_neon
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_neon
@@ -1116,9 +1574,6 @@
 void aom_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_neon
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_neon
@@ -1134,9 +1589,6 @@
 void aom_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_neon
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x128 aom_sad64x128_neon
@@ -1152,9 +1604,6 @@
 void aom_sad64x128x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x128x4d aom_sad64x128x4d_neon
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x32 aom_sad64x32_neon
@@ -1170,9 +1619,6 @@
 void aom_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x32x4d aom_sad64x32x4d_neon
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad64x64 aom_sad64x64_neon
@@ -1188,9 +1634,6 @@
 void aom_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad64x64x4d aom_sad64x64x4d_neon
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_neon
@@ -1206,9 +1649,6 @@
 void aom_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_neon
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_neon
@@ -1224,9 +1664,6 @@
 void aom_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_neon
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_neon
@@ -1242,9 +1679,6 @@
 void aom_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_neon
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad_skip_128x128 aom_sad_skip_128x128_neon
@@ -1764,57 +2198,117 @@
 #define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
 
 void aom_v_predictor_16x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+void aom_v_predictor_16x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_neon
 
 void aom_v_predictor_16x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+void aom_v_predictor_16x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_neon
 
 void aom_v_predictor_16x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+void aom_v_predictor_16x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_neon
 
 void aom_v_predictor_16x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+void aom_v_predictor_16x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_neon
 
 void aom_v_predictor_32x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+void aom_v_predictor_32x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_neon
 
 void aom_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
 
 void aom_v_predictor_32x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+void aom_v_predictor_32x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_neon
 
 void aom_v_predictor_32x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+void aom_v_predictor_32x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_neon
 
 void aom_v_predictor_4x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+void aom_v_predictor_4x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_neon
 
 void aom_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 #define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
 
 void aom_v_predictor_4x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+void aom_v_predictor_4x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_neon
 
 void aom_v_predictor_64x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+void aom_v_predictor_64x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_neon
 
 void aom_v_predictor_64x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+void aom_v_predictor_64x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_neon
 
 void aom_v_predictor_64x64_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+void aom_v_predictor_64x64_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_neon
 
 void aom_v_predictor_8x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+void aom_v_predictor_8x16_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_neon
 
 void aom_v_predictor_8x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+void aom_v_predictor_8x32_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_neon
 
 void aom_v_predictor_8x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
-#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+void aom_v_predictor_8x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_neon
 
 void aom_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
 void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left);
diff --git a/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
index 6dfd871..99a0c0a 100644
--- a/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
+++ b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
@@ -127,10 +127,22 @@
 #define av1_calc_frame_error av1_calc_frame_error_c
 
 void av1_calc_indices_dim1_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim1 av1_calc_indices_dim1_c
+void av1_calc_indices_dim1_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim1 av1_calc_indices_dim1_neon
 
 void av1_calc_indices_dim2_c(const int16_t *data, const int16_t *centroids, uint8_t *indices, int64_t *total_dist, int n, int k);
-#define av1_calc_indices_dim2 av1_calc_indices_dim2_c
+void av1_calc_indices_dim2_neon(const int16_t* data,
+                                const int16_t* centroids,
+                                uint8_t* indices,
+                                int64_t* total_dist,
+                                int n,
+                                int k);
+#define av1_calc_indices_dim2 av1_calc_indices_dim2_neon
 
 void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, const InterpFilterParams *filter_params_x, const InterpFilterParams *filter_params_y, const int subpel_x_qn, const int x_step_qn, const int subpel_y_qn, const int y_step_qn, ConvolveParams *conv_params);
 #define av1_convolve_2d_scale av1_convolve_2d_scale_c
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_config.asm b/third_party/libaom/source/config/win/ia32/config/aom_config.asm
index 690c8ce..e16c3ca 100644
--- a/third_party/libaom/source/config/win/ia32/config/aom_config.asm
+++ b/third_party/libaom/source/config/win/ia32/config/aom_config.asm
@@ -16,6 +16,7 @@
 %define CONFIG_COLLECT_COMPONENT_TIMING 0
 %define CONFIG_COLLECT_PARTITION_STATS 0
 %define CONFIG_COLLECT_RD_STATS 0
+%define CONFIG_CWG_C013 0
 %define CONFIG_DEBUG 0
 %define CONFIG_DENOISE 1
 %define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_config.h b/third_party/libaom/source/config/win/ia32/config/aom_config.h
index b88f04a..f8e5db9 100644
--- a/third_party/libaom/source/config/win/ia32/config/aom_config.h
+++ b/third_party/libaom/source/config/win/ia32/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/win/ia32/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/win/ia32/config/aom_dsp_rtcd.h
index 56fb931..d6d92891 100644
--- a/third_party/libaom/source/config/win/ia32/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/win/ia32/config/aom_dsp_rtcd.h
@@ -1287,9 +1287,6 @@
 void aom_sad128x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1309,9 +1306,6 @@
 void aom_sad128x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_sse2
@@ -1329,9 +1323,6 @@
 void aom_sad16x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_sse2
@@ -1349,9 +1340,6 @@
 void aom_sad16x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_sse2
@@ -1369,9 +1357,6 @@
 void aom_sad16x8x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1391,9 +1376,6 @@
 void aom_sad32x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1413,9 +1395,6 @@
 void aom_sad32x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1435,9 +1414,6 @@
 void aom_sad32x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_sse2
@@ -1453,9 +1429,6 @@
 void aom_sad4x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_sse2
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_sse2
@@ -1471,9 +1444,6 @@
 void aom_sad4x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_sse2
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1493,9 +1463,6 @@
 void aom_sad64x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1515,9 +1482,6 @@
 void aom_sad64x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1537,9 +1501,6 @@
 void aom_sad64x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_sse2
@@ -1555,9 +1516,6 @@
 void aom_sad8x16x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_sse2
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_sse2
@@ -1573,9 +1531,6 @@
 void aom_sad8x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_sse2
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_sse2
@@ -1591,9 +1546,6 @@
 void aom_sad8x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_sse2
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
diff --git a/third_party/libaom/source/config/win/x64/config/aom_config.asm b/third_party/libaom/source/config/win/x64/config/aom_config.asm
index 8526e15..149f97d7 100644
--- a/third_party/libaom/source/config/win/x64/config/aom_config.asm
+++ b/third_party/libaom/source/config/win/x64/config/aom_config.asm
@@ -16,6 +16,7 @@
 %define CONFIG_COLLECT_COMPONENT_TIMING 0
 %define CONFIG_COLLECT_PARTITION_STATS 0
 %define CONFIG_COLLECT_RD_STATS 0
+%define CONFIG_CWG_C013 0
 %define CONFIG_DEBUG 0
 %define CONFIG_DENOISE 1
 %define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/win/x64/config/aom_config.h b/third_party/libaom/source/config/win/x64/config/aom_config.h
index 8cd8dc1..41d0951 100644
--- a/third_party/libaom/source/config/win/x64/config/aom_config.h
+++ b/third_party/libaom/source/config/win/x64/config/aom_config.h
@@ -28,6 +28,7 @@
 #define CONFIG_COLLECT_COMPONENT_TIMING 0
 #define CONFIG_COLLECT_PARTITION_STATS 0
 #define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_CWG_C013 0
 #define CONFIG_DEBUG 0
 #define CONFIG_DENOISE 1
 #define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
diff --git a/third_party/libaom/source/config/win/x64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/win/x64/config/aom_dsp_rtcd.h
index b98b07b..7c32033 100644
--- a/third_party/libaom/source/config/win/x64/config/aom_dsp_rtcd.h
+++ b/third_party/libaom/source/config/win/x64/config/aom_dsp_rtcd.h
@@ -1289,9 +1289,6 @@
 void aom_sad128x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x128x4d_avg aom_sad128x128x4d_avg_c
-
 unsigned int aom_sad128x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad128x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1311,9 +1308,6 @@
 void aom_sad128x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad128x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad128x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad128x64x4d_avg aom_sad128x64x4d_avg_c
-
 unsigned int aom_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x16 aom_sad16x16_sse2
@@ -1331,9 +1325,6 @@
 void aom_sad16x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x16x4d_avg aom_sad16x16x4d_avg_c
-
 unsigned int aom_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x32 aom_sad16x32_sse2
@@ -1351,9 +1342,6 @@
 void aom_sad16x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x32x4d_avg aom_sad16x32x4d_avg_c
-
 unsigned int aom_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad16x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad16x8 aom_sad16x8_sse2
@@ -1371,9 +1359,6 @@
 void aom_sad16x8x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad16x8x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad16x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad16x8x4d_avg aom_sad16x8x4d_avg_c
-
 unsigned int aom_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x16_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1393,9 +1378,6 @@
 void aom_sad32x16x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x16x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x16x4d_avg aom_sad32x16x4d_avg_c
-
 unsigned int aom_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1415,9 +1397,6 @@
 void aom_sad32x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x32x4d_avg aom_sad32x32x4d_avg_c
-
 unsigned int aom_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad32x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1437,9 +1416,6 @@
 void aom_sad32x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad32x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad32x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad32x64x4d_avg aom_sad32x64x4d_avg_c
-
 unsigned int aom_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x4 aom_sad4x4_sse2
@@ -1455,9 +1431,6 @@
 void aom_sad4x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x4x4d aom_sad4x4x4d_sse2
 
-void aom_sad4x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x4x4d_avg aom_sad4x4x4d_avg_c
-
 unsigned int aom_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad4x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad4x8 aom_sad4x8_sse2
@@ -1473,9 +1446,6 @@
 void aom_sad4x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad4x8x4d aom_sad4x8x4d_sse2
 
-void aom_sad4x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad4x8x4d_avg aom_sad4x8x4d_avg_c
-
 unsigned int aom_sad64x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1495,9 +1465,6 @@
 void aom_sad64x128x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x128x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x128x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x128x4d_avg aom_sad64x128x4d_avg_c
-
 unsigned int aom_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x32_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1517,9 +1484,6 @@
 void aom_sad64x32x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x32x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x32x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x32x4d_avg aom_sad64x32x4d_avg_c
-
 unsigned int aom_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad64x64_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
@@ -1539,9 +1503,6 @@
 void aom_sad64x64x4d_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 RTCD_EXTERN void (*aom_sad64x64x4d)(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 
-void aom_sad64x64x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad64x64x4d_avg aom_sad64x64x4d_avg_c
-
 unsigned int aom_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x16_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x16 aom_sad8x16_sse2
@@ -1557,9 +1518,6 @@
 void aom_sad8x16x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x16x4d aom_sad8x16x4d_sse2
 
-void aom_sad8x16x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x16x4d_avg aom_sad8x16x4d_avg_c
-
 unsigned int aom_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x4_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x4 aom_sad8x4_sse2
@@ -1575,9 +1533,6 @@
 void aom_sad8x4x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x4x4d aom_sad8x4x4d_sse2
 
-void aom_sad8x4x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x4x4d_avg aom_sad8x4x4d_avg_c
-
 unsigned int aom_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad8x8_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 #define aom_sad8x8 aom_sad8x8_sse2
@@ -1593,9 +1548,6 @@
 void aom_sad8x8x4d_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, uint32_t sad_array[4]);
 #define aom_sad8x8x4d aom_sad8x8x4d_sse2
 
-void aom_sad8x8x4d_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[4], int ref_stride, const uint8_t *second_pred, uint32_t sad_array[4]);
-#define aom_sad8x8x4d_avg aom_sad8x8x4d_avg_c
-
 unsigned int aom_sad_skip_128x128_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_sse2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
 unsigned int aom_sad_skip_128x128_avx2(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride);
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index b323c00..4e39533 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 527621809
-Date: 2023/04/27 UTC
+Version: 529503149
+Date: 2023/05/04 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/structured_data.proto b/third_party/metrics_proto/structured_data.proto
index e62a0c36..a57dc18 100644
--- a/third_party/metrics_proto/structured_data.proto
+++ b/third_party/metrics_proto/structured_data.proto
@@ -150,4 +150,7 @@
 // structured events for that upload, and any other metadata.
 message StructuredDataProto {
   repeated StructuredEventProto events = 1;
+
+  // Whether the device is enrolled and may be controlled by a policy.
+  optional bool is_device_enrolled = 2;
 }
diff --git a/third_party/ruy/BUILD.gn b/third_party/ruy/BUILD.gn
index f326d82c..be324dd 100644
--- a/third_party/ruy/BUILD.gn
+++ b/third_party/ruy/BUILD.gn
@@ -3,19 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/arm.gni")
-
-use_cpuinfo =
-    # cpuinfo is not supported on these chips.
-    current_cpu != "ppc64" && current_cpu != "ppc64le" &&
-    current_cpu != "s390" && current_cpu != "s390x" &&
-    # cpuinfo is not supported on fuchsia.
-    !is_fuchsia &&
-    # There's a few arm architectures that are not supported by cpuinfo,
-    # especially amongst ChromeOS devices.
-    # See //third_party/cpuinfo/src/src/arm/linux/cp.h.
-    (!defined(arm_arch) ||
-     (arm_arch != "armv7-a+crc" && arm_arch != "armv8-a+crc" &&
-      arm_arch != "armv8-a+crc+crypto"))
+import("//third_party/cpuinfo/cpuinfo.gni")
 
 config("ruy_include") {
   include_dirs = [ "src" ]
diff --git a/third_party/tflite/BUILD.gn b/third_party/tflite/BUILD.gn
index 24ba2ebb..a57d566 100644
--- a/third_party/tflite/BUILD.gn
+++ b/third_party/tflite/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/sanitizers/sanitizers.gni")
+import("//third_party/cpuinfo/cpuinfo.gni")
 import("//third_party/protobuf/proto_library.gni")
 import("//third_party/tflite/features.gni")
 
@@ -409,6 +410,12 @@
     "//third_party/ruy",
   ]
 
+  if (use_cpuinfo) {
+    defines = ["TFLITE_HAVE_CPUINFO"]
+    deps += ["//third_party/cpuinfo"]
+    include_dirs = [ "//third_party/cpuinfo/src" ]
+  }
+
   configs += [
     ":tflite_config",
     ":tflite_flags",
diff --git a/tools/android/avd/proto/creation/generic_androidu.textpb b/tools/android/avd/proto/creation/generic_androidu.textpb
new file mode 100644
index 0000000..dc645fe
--- /dev/null
+++ b/tools/android/avd/proto/creation/generic_androidu.textpb
@@ -0,0 +1,36 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Configuration for a generic x86_64 android-U AVD (userdebug build).
+
+emulator_package {
+  package_name: "chromium/third_party/android_sdk/public/emulator"
+  version: "MSb1Vp2C8-H7iJoLte1wgL6oqDtFMLlpI8bppWCUL6EC"  # 32.1.12
+  dest_path: "generic_androidu"
+}
+
+system_image_package {
+  package_name: "chromium/third_party/android_sdk/public/system-images/android-upsidedowncake/google_apis/x86_64"
+  version: "KG8hpMcAc1OrhFZ-UBuYb3GwK7a-3TZRq8UJqBsg9owC"  # r3
+  dest_path: "generic_androidu"
+}
+system_image_name: "system-images;android-UpsideDownCake;google_apis;x86_64"
+
+avd_package {
+  package_name: "chromium/third_party/android_sdk/public/avds/android-upsidedowncake/google_apis/x86_64"
+  dest_path: "generic_androidu"
+}
+avd_name: "android_u_google_apis_x86_64"
+
+avd_settings {
+  screen {
+    density: 480
+    height: 1920
+    width: 1080
+  }
+  advanced_features {
+    key: "GLESDynamicVersion"
+    value: "on"
+  }
+}
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 6fcc21d..179bddf7 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -553,9 +553,6 @@
     "META": {"sizes": {"includes": [20],}},
     "includes": [2600],
   },
-  "content/dev_ui_content_resources.grd": {
-    "includes": [2620],
-  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/feed/resources.grd": {
     "META": {"sizes": {"includes": [20]}},
     "includes": [2640],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index c18f691..fe34ccb 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -452,6 +452,7 @@
       'linux-blink-wpt-reset-rel': 'release_bot_blink_minimal_symbols_reclient',
       'linux-build-perf-developer': 'developer',
       'linux-chromeos-annotator-rel': 'chromeos_with_codecs_release_bot_reclient',
+      'linux-cr23-rel': 'release_bot_minimal_symbols_reclient',
       'linux-fieldtrial-rel': 'release_bot_minimal_symbols_reclient',
       'linux-headless-shell-rel': 'headless_shell_release_bot_reclient',
       'linux-lacros-builder-fyi-rel': 'lacros_on_linux_release_bot_reclient',
@@ -471,6 +472,7 @@
       'linux-wpt-identity-fyi-rel': 'release_bot_minimal_symbols_reclient',
       'linux-wpt-input-fyi-rel': 'release_bot_minimal_symbols_reclient',
       'mac-backuprefptr-x64-fyi-rel': 'release_trybot_backuprefptr_x64_reclient',
+      'mac-cr23-rel': 'release_bot_minimal_symbols_reclient',
       'mac-osxbeta-rel': 'gpu_tests_debug_trybot_reclient',
       'mac-perfetto-rel': 'perfetto_release_bot_reclient',
       'mac-upload-perfetto': 'release_bot_perfetto_zlib_reclient',
@@ -485,6 +487,7 @@
       'win-backuprefptr-x86-fyi-rel': 'release_trybot_backuprefptr_x86_reclient',
       'win-build-perf-developer': 'developer',
       'win-celab-builder-rel': 'release_bot_minimal_symbols_reclient',
+      'win-cr23-rel': 'release_bot_minimal_symbols_reclient',
       'win-fieldtrial-rel': 'release_bot_minimal_symbols_reclient',
       'win-perfetto-rel': 'perfetto_release_bot_reclient',
       'win-upload-perfetto': 'release_bot_perfetto_zlib_reclient',
@@ -1212,6 +1215,7 @@
       'linux-centipede-asan-rel': 'centipede_asan_release_trybot_reclient',
       'linux-chromeos-code-coverage': 'chromeos_with_codecs_release_bot_coverage_reclient',
       'linux-code-coverage': 'clang_code_coverage_reclient',
+      'linux-cr23-rel': 'release_trybot_reclient',
       'linux-dcheck-off-rel': 'release_trybot_dcheck_off_reclient',
       'linux-extended-tracing-rel': 'release_trybot_extended_tracing_reclient',
       'linux-fieldtrial-rel': 'release_bot_minimal_symbols_reclient',
@@ -1310,6 +1314,7 @@
       'mac-arm64-on-arm64-rel': 'mac_arm64_release_trybot_reclient',
       'mac-builder-next': 'mac_arm64_gpu_tests_debug_bot_minimal_symbols_no_nacl_reclient',
       'mac-code-coverage': 'clang_code_coverage_reclient',
+      'mac-cr23-rel': 'release_trybot_minimal_symbols_reclient',
       'mac-fieldtrial-tester': 'mac_arm64_gpu_tests_release_bot_minimal_symbols_no_nacl_reclient',
       'mac-intel-on-arm64-rel': 'release_trybot_reclient_x64',
       'mac-inverse-fieldtrials-fyi-rel': 'gpu_tests_release_trybot_invert_fieldtrials_reclient',
@@ -1417,6 +1422,7 @@
       'win-annotator-rel': 'release_trybot_reclient',
       'win-asan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release_reclient',
       'win-celab-try-rel': 'release_bot_minimal_symbols_reclient',
+      'win-cr23-rel': 'release_trybot_reclient',
       'win-fieldtrial-rel': 'release_bot_minimal_symbols_reclient',
       'win-libfuzzer-asan-rel': 'libfuzzer_windows_asan_release_trybot_reclient',
       'win-perfetto-rel': 'perfetto_release_trybot_reclient',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 064e85f..46ddc0d 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -978,6 +978,15 @@
       "use_remoteexec": true
     }
   },
+  "linux-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 1,
+      "use_remoteexec": true
+    }
+  },
   "linux-fieldtrial-rel": {
     "gn_args": {
       "dcheck_always_on": false,
@@ -1176,6 +1185,15 @@
       "use_remoteexec": true
     }
   },
+  "mac-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 1,
+      "use_remoteexec": true
+    }
+  },
   "mac-osxbeta-rel": {
     "gn_args": {
       "dcheck_always_on": true,
@@ -1319,6 +1337,15 @@
       "use_remoteexec": true
     }
   },
+  "win-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 1,
+      "use_remoteexec": true
+    }
+  },
   "win-fieldtrial-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
index 72cfcc4..f8da936 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -301,6 +301,15 @@
       "use_remoteexec": true
     }
   },
+  "linux-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 0,
+      "use_remoteexec": true
+    }
+  },
   "linux-dcheck-off-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index ef5b73d..cb37c742 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -491,6 +491,15 @@
       "use_remoteexec": true
     }
   },
+  "mac-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 1,
+      "use_remoteexec": true
+    }
+  },
   "mac-fieldtrial-tester": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.win.json b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
index 905585a..4f5adb5 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.win.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
@@ -138,6 +138,15 @@
       "use_remoteexec": true
     }
   },
+  "win-cr23-rel": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "symbol_level": 0,
+      "use_remoteexec": true
+    }
+  },
   "win-fieldtrial-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index c37097b..f675d61 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -58970,6 +58970,7 @@
       label="AccessibilityChromeVoxPageMigration:disabled"/>
   <int value="-1821491797"
       label="AutofillEnableRankingFormulaCreditCards:enabled"/>
+  <int value="-1821336389" label="DiscardedTabTreatment:enabled"/>
   <int value="-1821058653" label="enable-delay-agnostic-aec"/>
   <int value="-1819497481" label="TouchTextEditingRedesign:disabled"/>
   <int value="-1818994562" label="ScanningAppJelly:enabled"/>
@@ -61758,6 +61759,7 @@
   <int value="-325271559" label="NtpRepeatableQueries:enabled"/>
   <int value="-324786035"
       label="EnableAmbientAuthenticationInGuestSession:enabled"/>
+  <int value="-324239279" label="DiscardedTabTreatment:disabled"/>
   <int value="-324099334" label="HatsUseNewHistograms:disabled"/>
   <int value="-323913169" label="PasswordNotesWithBackup:enabled"/>
   <int value="-323831744" label="token-binding:enabled"/>
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
index 32e5b59..2b8d35a 100644
--- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
+++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -349,6 +349,7 @@
 nyquist@chromium.org
 shaktisahu@chromium.org
 haileywang@google.com
+ritikagup@google.com
 # service
 wanderview@chromium.org
 ayui@chromium.org
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml
index 30e60745..5ae1504 100644
--- a/tools/metrics/histograms/metadata/commerce/histograms.xml
+++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -485,7 +485,7 @@
 </histogram>
 
 <histogram name="Commerce.ShoppingService.ProductInfo.FallbackDataContent"
-    enum="ShoppingDataProviderFallback" expires_after="2023-06-01">
+    enum="ShoppingDataProviderFallback" expires_after="2023-11-01">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
@@ -497,7 +497,7 @@
 </histogram>
 
 <histogram name="Commerce.ShoppingService.ProductInfo.FallbackDataUsed"
-    enum="Boolean" expires_after="2023-09-10">
+    enum="Boolean" expires_after="2023-11-01">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
@@ -508,7 +508,7 @@
 </histogram>
 
 <histogram name="Commerce.ShoppingService.ProductInfo.ImageAvailability"
-    enum="ProductImageAvailability" expires_after="2023-10-08">
+    enum="ProductImageAvailability" expires_after="2023-11-01">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 8b5f8fb..93af534 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -896,7 +896,7 @@
 
 <histogram
     name="CompositorLatency.CompositorOnlyFrame{InteractionType}.{StageType}"
-    units="microseconds" expires_after="2023-03-01">
+    units="microseconds" expires_after="2024-05-05">
   <owner>jonross@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -906,6 +906,8 @@
 
     This metric uses base::Histogram::FactoryMicrosecondsTimeGet so only users
     with high resolution clocks will report this metric.
+
+    Note: This metric was expired from 2023-03-01 to 2023-05-05.
   </summary>
   <token key="InteractionType">
     <variant name=""/>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index a3cac0c2..a5a3183 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -453,7 +453,8 @@
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
     Records whether the model execution for {OptimizationTarget} was cancelled
-    due to running past the configured timeout.
+    due to running past the configured timeout. In M115+ if batch execution is
+    used, this is recorded once per each input within the batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -466,7 +467,8 @@
   <summary>
     Records the time duration it took execute the model for
     {OptimizationTarget}. Recorded once per model execution for
-    {OptimizationTarget}.
+    {OptimizationTarget}. In M115+ if batch execution is used, this is recorded
+    once per each input within the batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -479,7 +481,8 @@
   <summary>
     Records the result of attempting to execute a {OptimizationTarget} model,
     including loading the file from disk. Recorded once per model execution
-    attempt for {OptimizationTarget}.
+    attempt for {OptimizationTarget}. In M115+ if batch execution is used, this
+    is recorded once per each input within the batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -494,7 +497,8 @@
     {OptimizationTarget}. Recorded once per model execution for
     {OptimizationTarget}. This is effectively the same as
     `OptimizationGuide.ModelExecutor.ExecutionLatency.{OptimizationTarget}` but
-    this is recorded using `base::ElapsedThreadTimer` instead.
+    this is recorded using `base::ElapsedThreadTimer` instead. In M115+ if batch
+    execution is used, this is recorded once per each input within the batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -551,7 +555,12 @@
   <summary>
     Records the execution latency for the {OptimizationTarget} model run by the
     model executor from when the task is posted from execution complete.
-    Recorded once per {OptimizationTarget} model execution attempt.
+    Recorded once per {OptimizationTarget} model execution attempt. In M115+ if
+    batch execution is used, this is recorded once per batch whether.
+
+    In M115, this was changed to always record the task execution latency
+    whether or not the task succeeded, whereas before it was only recorded on
+    success.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -564,7 +573,8 @@
   <summary>
     Records the duration a {OptimizationTarget} model execution request spent
     waiting for the background task queue to run the task. Recorded once per
-    {OptimizationTarget} model execution attempt.
+    {OptimizationTarget} model execution attempt. In M115+ if batch execution is
+    used, this is recorded once per batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
@@ -576,7 +586,8 @@
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
     Records the time duration between runs of the model for
-    {OptimizationTarget}. Recorded once for every model run after the first.
+    {OptimizationTarget}. Recorded once for every model run after the first. In
+    M115+ if batch execution is used, this is recorded once per batch.
   </summary>
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
diff --git a/tools/metrics/histograms/metadata/renderer/histograms.xml b/tools/metrics/histograms/metadata/renderer/histograms.xml
index 397fa1b0..9a61827 100644
--- a/tools/metrics/histograms/metadata/renderer/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer/histograms.xml
@@ -605,25 +605,6 @@
   </summary>
 </histogram>
 
-<histogram name="RendererScheduler.TaskTime2" units="microseconds"
-    expires_after="never">
-  <owner>sunyunjia@chromium.org</owner>
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    The duration of every task queued in the _renderer_ scheduler to see the
-    distribution of the task duration.
-
-    Note that this metric discards tasks longer than 30 seconds because they are
-    considered to be a result of measurement glitch.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
 <histogram name="RendererSyncIPC.ElapsedTime" units="ms" expires_after="M85">
   <owner>ppi@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/segmentation_platform/OWNERS b/tools/metrics/histograms/metadata/segmentation_platform/OWNERS
index a57d0ca..8aca9f405e 100644
--- a/tools/metrics/histograms/metadata/segmentation_platform/OWNERS
+++ b/tools/metrics/histograms/metadata/segmentation_platform/OWNERS
@@ -5,3 +5,4 @@
 nyquist@chromium.org
 shaktisahu@chromium.org
 haileywang@google.com
+ritikagup@google.com
diff --git a/tools/metrics/histograms/metadata/variations/histograms.xml b/tools/metrics/histograms/metadata/variations/histograms.xml
index be29ce5e..7ae914b 100644
--- a/tools/metrics/histograms/metadata/variations/histograms.xml
+++ b/tools/metrics/histograms/metadata/variations/histograms.xml
@@ -140,7 +140,7 @@
 </histogram>
 
 <histogram name="Variations.ExtendedSafeMode.BeaconFileWrite"
-    enum="BooleanSuccess" expires_after="2023-05-31">
+    enum="BooleanSuccess" expires_after="2023-10-31">
   <owner>caitlinfischer@google.com</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <component>Internals&gt;Metrics&gt;Variations</component>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 298c6a1..66cad0d 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": "perfetto-luci-artifacts/v34.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "c1885a5ea815604c0e4bfe915e2a42ffd944e807",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/13e29bf7ebded622605407f42dd0a7bc6892a65b/trace_processor_shell.exe"
+            "hash": "5bb5864ab84b977bb49588f66cee88e28109a791",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/5acf8796c8d042aa5671f87a02369889f3c89c96/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "336a42cb9ec3c417e13a97816271fec10cdf67e5",
             "full_remote_path": "perfetto-luci-artifacts/v34.0/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "ce48a2a8ad2d7557d828f79b8196986178e2d695",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/093521a70f8d1732bb4476ebb60ed1ee1440af99/trace_processor_shell"
+            "hash": "cfbffa1175f5d34cf4d2d5cd2c7cad45fcc42092",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/564d5514641afc4f77d1415faf1a7853f83db911/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "c32364e05e22cdf82ee0866aedd11c0e2050809c",
             "full_remote_path": "perfetto-luci-artifacts/v34.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "c6e69ec782994556e81e64bd3f30a7770b8b10b2",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/093521a70f8d1732bb4476ebb60ed1ee1440af99/trace_processor_shell"
+            "hash": "3c83c160e7c9e9d35e4ee8be48cf4b143f18a0ef",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6087bfd57d4cdb4eda85c9b32b73b3b55e48ad87/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/page_sets/data/credentials.json.sha1 b/tools/perf/page_sets/data/credentials.json.sha1
index 0a64a956..01e1378f 100644
--- a/tools/perf/page_sets/data/credentials.json.sha1
+++ b/tools/perf/page_sets/data/credentials.json.sha1
@@ -1 +1 @@
-721318da8f30da59bf606814df67d449ea7f5986
\ No newline at end of file
+9aefd832456afa8800ccb1613a54028b6cb8cad4
\ No newline at end of file
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py
index 82dd491..51c44c41 100755
--- a/tools/rust/build_rust.py
+++ b/tools/rust/build_rust.py
@@ -39,6 +39,7 @@
 import json
 import platform
 import os
+import re
 import shutil
 import string
 import subprocess
@@ -86,6 +87,9 @@
 EXCLUDED_TESTS_WINDOWS = [
     # https://github.com/rust-lang/rust/issues/96464
     os.path.join('tests', 'codegen', 'vec-shrink-panik.rs'),
+    # TODO(crbug.com/1442943): Re-enable when fixed.
+    os.path.join('tests', 'ui', 'native-library-link-flags',
+                 'msvc-non-utf8-output.rs'),
 ]
 
 CLANG_SCRIPTS_DIR = os.path.join(THIS_DIR, '..', 'clang', 'scripts')
@@ -94,6 +98,8 @@
                 'github.com/rust-lang/rust')
 
 RUST_SRC_DIR = os.path.join(THIRD_PARTY_DIR, 'rust_src', 'src')
+RUST_BOOTSTRAP_DIST_RS = os.path.join(RUST_SRC_DIR, 'src', 'bootstrap',
+                                      'dist.rs')
 STAGE0_JSON_PATH = os.path.join(RUST_SRC_DIR, 'src', 'stage0.json')
 # Download crates.io dependencies to rust-src subdir (rather than $HOME/.cargo)
 CARGO_HOME_DIR = os.path.join(RUST_SRC_DIR, 'cargo-home')
@@ -253,6 +259,42 @@
 
 def CargoVendor(cargo_bin):
     '''Runs `cargo vendor` to pull down dependencies.'''
+    # From https://github.com/rust-lang/rust/blob/4a18324a4df6bc98bec0b54d35908d7a9cdc7c32/src/bootstrap/dist.rs#L1008-L1015:
+    # The additional `--sync` Cargo.toml files are not part of the top level
+    # workspace.
+    SYNC_TARGETS = [
+        './src/tools/cargo/Cargo.toml',
+        './src/tools/rust-analyzer/Cargo.toml',
+        './compiler/rustc_codegen_cranelift/Cargo.toml',
+        './src/bootstrap/Cargo.toml',
+    ]
+
+    # Try to verify our sync targets match the upstream nightly tarball
+    # builder's.
+    BUILDER_REGEX = (r'(?:'
+                     r'\s*\.arg\("--sync"\)'
+                     r'\s*\.arg\(builder.src.join\("(?P<target>[^"]+)"\)\)'
+                     r')')
+    content = ''
+    with open(RUST_BOOTSTRAP_DIST_RS) as f:
+        content = ''.join([line.strip() for line in f])
+    upstream_sync_targets = re.compile(BUILDER_REGEX).findall(content)
+    error = False
+    for s in SYNC_TARGETS:
+        if not s in upstream_sync_targets:
+            print(f'Upstream bootstrap/dist.rs removed "--sync {s}", '
+                  'so it should be removed from SYNC_TARGETS in '
+                  '//tools/rust/build_rust.py.')
+            error = True
+    for s in upstream_sync_targets:
+        if not s in SYNC_TARGETS:
+            print(f'Upstream bootstrap/dist.rs added "--sync {s}", '
+                  'so it should be added to SYNC_TARGETS in '
+                  '//tools/rust/build_rust.py.')
+            error = True
+    if error:
+        sys.exit(1)
+
     os.chdir(RUST_SRC_DIR)
 
     for i in range(0, 3):
@@ -270,23 +312,14 @@
         else:
             sys.exit(1)
 
-        # From https://github.com/rust-lang/rust/blob/master/src/bootstrap/dist.rs#L1003-L1013:
-        # The additional `--sync` Cargo.toml files are not part of the top level
-        # workspace.
         vendor_cmd = [
             cargo_bin,
             'vendor',
             '--locked',
             '--versioned-dirs',
-            '--sync',
-            'src/tools/cargo/Cargo.toml',
-            '--sync',
-            'src/tools/rust-analyzer/Cargo.toml',
-            '--sync',
-            'compiler/rustc_codegen_cranelift/Cargo.toml',
-            '--sync',
-            'src/bootstrap/Cargo.toml',
         ]
+        for s in SYNC_TARGETS:
+            vendor_cmd.extend(['--sync', s])
         if RunCommand(vendor_cmd, fail_hard=False):
             break  # Success, break out of the retry loop.
         elif i < 2:
diff --git a/tools/rust/update_rust.py b/tools/rust/update_rust.py
index b39a5b3..81dd3f8 100755
--- a/tools/rust/update_rust.py
+++ b/tools/rust/update_rust.py
@@ -192,7 +192,6 @@
         shutil.rmtree(RUST_TOOLCHAIN_OUT_DIR)
 
     try:
-        platform_prefix = GetPlatformUrlPrefix(GetDefaultHostOs())
         DownloadAndUnpack(url, THIRD_PARTY_DIR)
     except urllib.error.HTTPError as e:
         print(f'error: Failed to download Rust package')
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index af19e9b..a46408b 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -300,7 +300,7 @@
  <item id="download_bitmap" added_in_milestone="98" content_hash_code="0632ef37" os_list="android" file_path="chrome/browser/share/bitmap_download_request.cc" />
  <item id="permission_request_creator" added_in_milestone="98" content_hash_code="04629d73" os_list="android,chromeos,linux,windows" file_path="chrome/browser/supervised_user/child_accounts/permission_request_creator_apiary.cc" />
  <item id="kids_chrome_management_client_classify_url" added_in_milestone="98" content_hash_code="003a8b30" os_list="android,chromeos,linux,windows" file_path="components/supervised_user/core/browser/kids_chrome_management_client.cc" />
- <item id="kids_chrome_management_list_family_members" added_in_milestone="106" content_hash_code="0709ea52" os_list="android,chromeos,linux,windows" file_path="components/supervised_user/core/browser/kids_external_fetcher.cc" />
+ <item id="kids_chrome_management_list_family_members" added_in_milestone="106" content_hash_code="023f7fa9" os_list="android,chromeos,windows,linux" file_path="components/supervised_user/core/browser/kids_external_fetcher_config.cc" />
  <item id="cached_image_fetcher" added_in_milestone="98" content_hash_code="06334a2d" os_list="android" file_path="components/image_fetcher/image_fetcher_bridge.cc" />
  <item id="chrome_cast_discovery_api" added_in_milestone="98" content_hash_code="0502b792" os_list="linux,windows,chromeos" file_path="chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc" />
  <item id="fedcm" added_in_milestone="98" content_hash_code="082197eb" os_list="linux,windows,chromeos,android" file_path="content/browser/webid/idp_network_request_manager.cc" />
diff --git a/ui/events/android/motion_event_android.cc b/ui/events/android/motion_event_android.cc
index f63ac22..58a230c0 100644
--- a/ui/events/android/motion_event_android.cc
+++ b/ui/events/android/motion_event_android.cc
@@ -542,6 +542,11 @@
       AttachCurrentThread(), event_, pointer_index, historical_index));
 }
 
+int MotionEventAndroid::GetSourceDeviceId(size_t pointer_index) const {
+  // Source device id is not supported.
+  return -1;
+}
+
 ui::MotionEvent::ToolType MotionEventAndroid::GetToolType(
     size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
diff --git a/ui/events/android/motion_event_android.h b/ui/events/android/motion_event_android.h
index 48a525d..4f0f356 100644
--- a/ui/events/android/motion_event_android.h
+++ b/ui/events/android/motion_event_android.h
@@ -112,6 +112,7 @@
                        size_t historical_index) const override;
   float GetHistoricalY(size_t pointer_index,
                        size_t historical_index) const override;
+  int GetSourceDeviceId(size_t pointer_index) const override;
   ToolType GetToolType(size_t pointer_index) const override;
   int GetButtonState() const override;
   int GetFlags() const override;
diff --git a/ui/views/view.cc b/ui/views/view.cc
index d7ebfb6..d7ec5ad 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -2722,6 +2722,9 @@
                                                               this);
     }
   }
+  for (auto& observer : observers_) {
+    observer.OnViewPropertyChanged(this, key, old_value);
+  }
 }
 
 void View::OnPropertyChanged(ui::metadata::PropertyKey property,
diff --git a/ui/views/view_observer.h b/ui/views/view_observer.h
index 49c6d7b..fdd0c50f 100644
--- a/ui/views/view_observer.h
+++ b/ui/views/view_observer.h
@@ -5,6 +5,8 @@
 #ifndef UI_VIEWS_VIEW_OBSERVER_H_
 #define UI_VIEWS_VIEW_OBSERVER_H_
 
+#include <stdint.h>
+
 #include "ui/views/views_export.h"
 
 namespace views {
@@ -74,6 +76,13 @@
   // Called immediately after |observed_view| has lost focus.
   virtual void OnViewBlurred(View* observed_view) {}
 
+  // Called immediately after the property associated with the specified
+  // |key| has been changed for the |observed_view|. The |old_value| must be
+  // cast to the appropriate type before use, see |ui::ClassPropertyCaster|.
+  virtual void OnViewPropertyChanged(View* observed_view,
+                                     const void* key,
+                                     int64_t old_value) {}
+
  protected:
   virtual ~ViewObserver() = default;
 };
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 62520a0e..e28c22f 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -61,6 +61,7 @@
 #include "ui/views/test/view_metadata_test_utils.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/test/widget_test.h"
+#include "ui/views/view_class_properties.h"
 #include "ui/views/view_observer.h"
 #include "ui/views/view_utils.h"
 #include "ui/views/views_features.h"
@@ -69,7 +70,14 @@
 #include "ui/views/widget/unique_widget_ptr.h"
 #include "ui/views/window/dialog_delegate.h"
 
-using testing::ElementsAre;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::IsNull;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::StrictMock;
+using ::testing::WithArg;
 
 namespace {
 
@@ -6426,6 +6434,63 @@
   EXPECT_EQ(child_view2, view_reordered());
 }
 
+class MockViewObserver : public ViewObserver {
+ public:
+  // ViewObserver:
+  MOCK_METHOD(void,
+              OnViewPropertyChanged,
+              (View * observed_view, const void* key, int64_t old_value),
+              (override));
+};
+
+ACTION_TEMPLATE(ExpectThatViewProperty,
+                HAS_1_TEMPLATE_PARAMS(typename, T),
+                AND_1_VALUE_PARAMS(Matcher)) {
+  EXPECT_THAT(ui::ClassPropertyCaster<T*>::FromInt64(arg0), Matcher);
+}
+
+TEST_F(ViewObserverTest, ViewPropertyChanged) {
+  // Create `view`.
+  std::unique_ptr<View> view = NewView();
+
+  // Observe `view`.
+  StrictMock<MockViewObserver> view_observer;
+  base::ScopedObservation<View, ViewObserver> view_observation(&view_observer);
+  view_observation.Observe(view.get());
+
+  constexpr auto kNewValue = gfx::Insets::TLBR(1, 2, 3, 4);
+
+  // Expect that setting `kNewValue` to the `kMarginsKey` will notify observers.
+  // Because a property at `kMarginsKey` was not previously set, the `old_value`
+  // should be a `nullptr`.
+  EXPECT_CALL(
+      view_observer,
+      OnViewPropertyChanged(Eq(view.get()), Eq(kMarginsKey), /*old_value*/ _))
+      .WillOnce(WithArg<2>(ExpectThatViewProperty<gfx::Insets>(IsNull())));
+
+  // Set `kNewValue` to `kMarginsKey` and verify expectations.
+  view->SetProperty(kMarginsKey, kNewValue);
+  Mock::VerifyAndClearExpectations(&view_observer);
+  EXPECT_THAT(view->GetProperty(kMarginsKey), Pointee(Eq(kNewValue)));
+
+  constexpr auto kPreviousValue = kNewValue;
+  constexpr auto kAnotherNewValue = gfx::Insets::TLBR(5, 6, 7, 8);
+
+  // Expect that setting `kAnotherNewValue` to the `kMarginsKey` will notify
+  // observers. Because a property at `kMarginsKey` was previously set, the
+  // `old_value` should point to the `kPreviousValue`.
+  EXPECT_CALL(
+      view_observer,
+      OnViewPropertyChanged(Eq(view.get()), Eq(kMarginsKey), /*old_value=*/_))
+      .WillOnce(WithArg<2>(
+          ExpectThatViewProperty<gfx::Insets>(Pointee(Eq(kPreviousValue)))));
+
+  // Set `kAnotherNewValue` to `kMarginsKey` and verify expectations.
+  view->SetProperty(kMarginsKey, kAnotherNewValue);
+  Mock::VerifyAndClearExpectations(&view_observer);
+  EXPECT_THAT(view->GetProperty(kMarginsKey), Pointee(Eq(kAnotherNewValue)));
+}
+
 // Provides a simple parent view implementation which tracks layer change
 // notifications from child views.
 class TestParentView : public View {
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn
index 625f7625..1100185 100644
--- a/weblayer/BUILD.gn
+++ b/weblayer/BUILD.gn
@@ -512,7 +512,6 @@
     "//components/webdata_services",
     "//components/webrtc",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//content/public/app",
     "//content/public/browser",
     "//content/public/child",
diff --git a/weblayer/shell/BUILD.gn b/weblayer/shell/BUILD.gn
index 68fdf10..ee90316 100644
--- a/weblayer/shell/BUILD.gn
+++ b/weblayer/shell/BUILD.gn
@@ -147,7 +147,6 @@
     "$root_gen_dir/components/strings/components_locale_settings_en-US.pak",
     "$root_gen_dir/components/strings/components_strings_en-US.pak",
     "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
     "$root_gen_dir/net/net_resources.pak",
     "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
@@ -165,7 +164,6 @@
     "//components/resources",
     "//components/strings",
     "//content:content_resources",
-    "//content:dev_ui_content_resources",
     "//mojo/public/js:resources",
     "//net:net_resources",
     "//third_party/blink/public:resources",