diff --git a/DEPS b/DEPS
index a49e01f..0aa8c45 100644
--- a/DEPS
+++ b/DEPS
@@ -297,15 +297,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': 'd04b56eca130c63da312a9b7ec8d40094564f428',
+  'skia_revision': '20402f8a42927a61657dc1723bb3949cfcff0184',
   # 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': '2da5616653aad70f55fb8d785fae65114b91cc5f',
+  'v8_revision': 'b777d8384fa02d477e914e42c17ba4b10d399d3c',
   # 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': '00a9787e3242a31ec224f97995cc6216f87c7b6b',
+  'angle_revision': 'c0818a182b5e91eb2f524f1cf5319f5398530a92',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -320,11 +320,11 @@
   #
   # Note this revision should be updated with
   # third_party/boringssl/roll_boringssl.py, not roll-dep.
-  'boringssl_revision': 'b95124305ab15c7523d3e21437309fa5dd717ee8',
+  'boringssl_revision': 'adaa322b63d1bfbd1abcf4a308926a9a83a6acbe',
   # 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:9.20220803.1.1',
+  'fuchsia_version': 'version:9.20220803.3.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.
@@ -368,7 +368,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': '47a2365de2ea5e4d233f5fdb4db2e2501edfe94f',
+  'catapult_revision': '97daa816fc4ad088cf4be1917c3339255eaa1e28',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -412,7 +412,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': '3c797eba3b555405f9b16ad5bc0a17a2c28c223c',
+  'dawn_revision': 'e40bd8e9641296b45f89c36bc058191b26052e87',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -440,7 +440,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
-  'nearby_revision': 'a732616a979b6761100dd53949eed4fc4070a93f',
+  'nearby_revision': '319e5abea448dccff02541d83f1816e0e5a8a8f5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling securemessage
   # and whatever else without interference from each other.
@@ -773,7 +773,7 @@
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'd065cbfff30c5eabd423510b58b2ccd64fd66d07',
+    'url': Var('chromium_git') + '/website.git' + '@' + '8396d7653f6a5b74319722d79c54a46a7504b39b',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -985,7 +985,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_build_tools/aapt2',
-              'version': 'hf9C5IyJUUGaBnzqu60xiFJSyfAmjqjc_PiNXNVc9l0C',
+              'version': 'nSnWUNu6ssPA-kPMvFQj4JjDXRWj2iubvvjfT1F6HCMC',
           },
       ],
       'condition': 'checkout_android',
@@ -1156,7 +1156,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' + '@' + '6c79d3da0da8f66c31b6a5ae20374b2af03c63a5',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'd391be8a4325cc57f37dc77c6c24248b409af0f4',
       'condition': 'checkout_chromeos',
   },
 
@@ -1732,7 +1732,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '94fd83896c67bb1a995337c501bbed02bd63361f',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '70ed471836560569467e00b0c23c5ff56f007137',
+    Var('webrtc_git') + '/src.git' + '@' + 'cc76c567abe59203b28501370ab43f967e1b98b5',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1805,7 +1805,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9c58769d85bdcec073e175c98708c92ceb9492eb',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d5209604cb24074b46171b8e0cc367c5021f0e0f',
     'condition': 'checkout_src_internal',
   },
 
@@ -1857,7 +1857,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'rxMZUoSzn5bPwQ_1ZR1RDfWFcxwE-Nt-zYkx0mpyvMgC',
+        'version': 'EapC761Sypj2L6fZ12iqUeJRwPQHcE4O7ALXYs__1goC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc
index 6ab0e36..8054f1f 100644
--- a/ash/app_list/views/app_list_bubble_view.cc
+++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -246,13 +246,7 @@
 
   search_box_view_ = contents->AddChildView(std::make_unique<SearchBoxView>(
       /*delegate=*/this, view_delegate_, /*app_list_view=*/nullptr));
-  SearchBoxViewBase::InitParams params;
-  // Show the assistant button until the user types text.
-  params.show_close_button_when_active = false;
-  params.create_background = false;
-  params.animate_changing_search_icon = false;
-  params.increase_child_view_padding = true;
-  search_box_view_->Init(params);
+  search_box_view_->InitializeForBubbleLauncher();
 
   // Skip the assistant button on arrow up/down in app list.
   button_focus_skipper_ = std::make_unique<ButtonFocusSkipper>();
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index 01df7942..3f6e267 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -656,11 +656,7 @@
   auto app_list_main_view = std::make_unique<AppListMainView>(delegate_, this);
   search_box_view_ =
       new SearchBoxView(app_list_main_view.get(), delegate_, this);
-  SearchBoxViewBase::InitParams params;
-  params.show_close_button_when_active = true;
-  params.create_background = true;
-  params.animate_changing_search_icon = true;
-  search_box_view_->Init(params);
+  search_box_view_->InitializeForFullscreenLauncher();
 
   // Assign |app_list_main_view_| here since it is accessed during Init().
   app_list_main_view_ = app_list_main_view.get();
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index 3f26dcb4..cced0799 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -214,25 +214,56 @@
       is_tablet_mode_(view_delegate_->IsInTabletMode()) {
   AppListModelProvider* const model_provider = AppListModelProvider::Get();
   model_provider->AddObserver(this);
-  search_box_model_observer_.Observe(
-      model_provider->search_model()->search_box());
+  SearchBoxModel* const search_box_model =
+      model_provider->search_model()->search_box();
+  search_box_model_observer_.Observe(search_box_model);
+
+  views::ImageButton* close_button = CreateCloseButton(base::BindRepeating(
+      &SearchBoxView::CloseButtonPressed, base::Unretained(this)));
+  std::u16string close_button_label(
+      l10n_util::GetStringUTF16(IDS_APP_LIST_CLEAR_SEARCHBOX));
+  close_button->SetAccessibleName(close_button_label);
+  close_button->SetTooltipText(close_button_label);
+
+  views::ImageButton* assistant_button =
+      CreateAssistantButton(base::BindRepeating(
+          &SearchBoxView::AssistantButtonPressed, base::Unretained(this)));
+  assistant_button->SetFlipCanvasOnPaintForRTLUI(false);
+  std::u16string assistant_button_label(
+      l10n_util::GetStringUTF16(IDS_APP_LIST_START_ASSISTANT));
+  assistant_button->SetAccessibleName(assistant_button_label);
+  assistant_button->SetTooltipText(assistant_button_label);
+  SetShowAssistantButton(search_box_model->show_assistant_button());
 }
 
 SearchBoxView::~SearchBoxView() {
   AppListModelProvider::Get()->RemoveObserver(this);
 }
 
-void SearchBoxView::Init(const InitParams& params) {
+void SearchBoxView::InitializeForBubbleLauncher() {
+  SearchBoxViewBase::InitParams params;
+  params.show_close_button_when_active = false;
+  params.create_background = false;
+  params.animate_changing_search_icon = false;
+  params.increase_child_view_padding = true;
+  // Add margins to the text field because the BoxLayout vertical centering
+  // does not properly align the text baseline with the icons.
+  params.textfield_margins = kTextFieldMarginsForAppListBubble;
+
   SearchBoxViewBase::Init(params);
+
   UpdatePlaceholderTextAndAccessibleName();
-  current_query_ = search_box()->GetText();
-  if (is_app_list_bubble_) {
-    // Add margins to the text field because the BoxLayout vertical centering
-    // does not properly align the text baseline with the icons.
-    search_box()->SetProperty(views::kMarginsKey,
-                              kTextFieldMarginsForAppListBubble);
-  }
-  ShowAssistantChanged();
+}
+
+void SearchBoxView::InitializeForFullscreenLauncher() {
+  SearchBoxViewBase::InitParams params;
+  params.show_close_button_when_active = true;
+  params.create_background = true;
+  params.animate_changing_search_icon = true;
+
+  SearchBoxViewBase::Init(params);
+
+  UpdatePlaceholderTextAndAccessibleName();
 }
 
 void SearchBoxView::SetResultSelectionController(
@@ -373,20 +404,6 @@
     view_delegate_->StartSearch(new_query);
 }
 
-void SearchBoxView::UpdateSearchIcon() {
-  const bool search_engine_is_google =
-      AppListModelProvider::Get()->search_model()->search_engine_is_google();
-  const gfx::VectorIcon& google_icon = is_search_box_active()
-                                           ? vector_icons::kGoogleColorIcon
-                                           : kGoogleBlackIcon;
-  const gfx::VectorIcon& icon =
-      search_engine_is_google ? google_icon : kSearchEngineNotGoogleIcon;
-  SetSearchIconImage(
-      gfx::CreateVectorIcon(icon, GetSearchBoxIconSize(),
-                            AppListColorProvider::Get()->GetSearchBoxIconColor(
-                                SkColorSetARGB(0xDE, 0x00, 0x00, 0x00))));
-}
-
 void SearchBoxView::UpdatePlaceholderTextStyle() {
   if (is_app_list_bubble_) {
     // The bubble launcher text is always side-aligned.
@@ -457,8 +474,16 @@
 
 void SearchBoxView::OnThemeChanged() {
   SearchBoxViewBase::OnThemeChanged();
-  SetupAssistantButton();
-  SetupCloseButton();
+  close_button()->SetImage(
+      views::ImageButton::STATE_NORMAL,
+      gfx::CreateVectorIcon(views::kIcCloseIcon, GetSearchBoxIconSize(),
+                            AppListColorProvider::Get()->GetSearchBoxIconColor(
+                                gfx::kGoogleGrey700)));
+  assistant_button()->SetImage(
+      views::ImageButton::STATE_NORMAL,
+      gfx::CreateVectorIcon(chromeos::kAssistantIcon, GetSearchBoxIconSize(),
+                            AppListColorProvider::Get()->GetSearchBoxIconColor(
+                                gfx::kGoogleGrey700)));
   OnWallpaperColorsChanged();
 }
 
@@ -480,20 +505,6 @@
   }
 }
 
-void SearchBoxView::SetupCloseButton() {
-  views::ImageButton* close = close_button();
-  close->SetImage(
-      views::ImageButton::STATE_NORMAL,
-      gfx::CreateVectorIcon(views::kIcCloseIcon, GetSearchBoxIconSize(),
-                            AppListColorProvider::Get()->GetSearchBoxIconColor(
-                                gfx::kGoogleGrey700)));
-  close->SetVisible(false);
-  std::u16string close_button_label(
-      l10n_util::GetStringUTF16(IDS_APP_LIST_CLEAR_SEARCHBOX));
-  close->SetAccessibleName(close_button_label);
-  close->SetTooltipText(close_button_label);
-}
-
 void SearchBoxView::SetupBackButton() {
   views::ImageButton* back = back_button();
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
@@ -537,6 +548,11 @@
 }
 
 void SearchBoxView::OnSearchBoxActiveChanged(bool active) {
+  UpdateSearchIcon();
+
+  // Clear ghost text when toggling search box active state.
+  MaybeSetAutocompleteGhostText(std::u16string(), std::u16string());
+
   if (active) {
     result_selection_controller_->ResetSelection(nullptr,
                                                  true /* default_selection */);
@@ -589,7 +605,7 @@
     return;
   }
 
-  SearchBoxViewBase::OnKeyEvent(evt);
+  delegate()->OnSearchBoxKeyEvent(evt);
 }
 
 bool SearchBoxView::OnMouseWheel(const ui::MouseWheelEvent& event) {
@@ -837,6 +853,28 @@
   return kClassicSearchBoxButtonSizeDip;
 }
 
+void SearchBoxView::CloseButtonPressed() {
+  delegate()->CloseButtonPressed();
+}
+
+void SearchBoxView::AssistantButtonPressed() {
+  delegate()->AssistantButtonPressed();
+}
+
+void SearchBoxView::UpdateSearchIcon() {
+  const bool search_engine_is_google =
+      AppListModelProvider::Get()->search_model()->search_engine_is_google();
+  const gfx::VectorIcon& google_icon = is_search_box_active()
+                                           ? vector_icons::kGoogleColorIcon
+                                           : kGoogleBlackIcon;
+  const gfx::VectorIcon& icon =
+      search_engine_is_google ? google_icon : kSearchEngineNotGoogleIcon;
+  SetSearchIconImage(
+      gfx::CreateVectorIcon(icon, GetSearchBoxIconSize(),
+                            AppListColorProvider::Get()->GetSearchBoxIconColor(
+                                SkColorSetARGB(0xDE, 0x00, 0x00, 0x00))));
+}
+
 bool SearchBoxView::IsValidAutocompleteText(
     const std::u16string& autocomplete_text) {
   // Don't set autocomplete text if it's the same as current search box
@@ -1273,17 +1311,4 @@
   highlight_range_.set_end(text_length);
 }
 
-void SearchBoxView::SetupAssistantButton() {
-  views::ImageButton* assistant = assistant_button();
-  assistant->SetImage(
-      views::ImageButton::STATE_NORMAL,
-      gfx::CreateVectorIcon(chromeos::kAssistantIcon, GetSearchBoxIconSize(),
-                            AppListColorProvider::Get()->GetSearchBoxIconColor(
-                                gfx::kGoogleGrey700)));
-  std::u16string assistant_button_label(
-      l10n_util::GetStringUTF16(IDS_APP_LIST_START_ASSISTANT));
-  assistant->SetAccessibleName(assistant_button_label);
-  assistant->SetTooltipText(assistant_button_label);
-}
-
 }  // namespace ash
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h
index f71ec1d..ab1129b 100644
--- a/ash/app_list/views/search_box_view.h
+++ b/ash/app_list/views/search_box_view.h
@@ -58,6 +58,14 @@
 
   ~SearchBoxView() override;
 
+  // Initializes the search box style for usage in bubble (clamshell mode)
+  // launcher.
+  void InitializeForBubbleLauncher();
+
+  // Initializes the search box style for usage in fullscreen (tablet mode)
+  // launcher.
+  void InitializeForFullscreenLauncher();
+
   // Must be called before the user interacts with the search box. Cannot be
   // part of Init() because the controller isn't available until after Init()
   // is called.
@@ -76,18 +84,14 @@
   void MaybeCreateFocusRing();
 
   // Overridden from SearchBoxViewBase:
-  void Init(const InitParams& params) override;
   void UpdateSearchTextfieldAccessibleNodeData(
       ui::AXNodeData* node_data) override;
   void ClearSearch() override;
   void HandleSearchBoxEvent(ui::LocatedEvent* located_event) override;
   void UpdateKeyboardVisibility() override;
   void UpdateModel(bool initiated_by_user) override;
-  void UpdateSearchIcon() override;
   void UpdatePlaceholderTextStyle() override;
   void UpdateSearchBoxBorder() override;
-  void SetupAssistantButton() override;
-  void SetupCloseButton() override;
   void SetupBackButton() override;
   void RecordSearchBoxActivationHistogram(ui::EventType event_type) override;
   void OnSearchBoxActiveChanged(bool active) override;
@@ -174,6 +178,15 @@
  private:
   class FocusRingLayer;
 
+  // Called when the close button within the search box gets pressed.
+  void CloseButtonPressed();
+
+  // Called when the assistant button within the search box gets pressed.
+  void AssistantButtonPressed();
+
+  // Updates the icon shown left of the search box texfield.
+  void UpdateSearchIcon();
+
   // Whether 'autocomplete_text' is a valid candidate for classic highlighted
   // autocomplete.
   bool IsValidAutocompleteText(const std::u16string& autocomplete_text);
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc
index 783c0a0c..397fa10 100644
--- a/ash/app_list/views/search_box_view_unittest.cc
+++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -146,10 +146,11 @@
       view = std::make_unique<SearchBoxView>(this, &view_delegate_,
                                              app_list_view_);
     }
-    SearchBoxViewBase::InitParams params;
-    params.show_close_button_when_active = true;
-    params.create_background = true;
-    view->Init(params);
+
+    if (IsProductivityLauncherEnabled())
+      view->InitializeForBubbleLauncher();
+    else
+      view->InitializeForFullscreenLauncher();
     view_ = widget_->GetContentsView()->AddChildView(std::move(view));
 
     if (IsProductivityLauncherEnabled()) {
@@ -271,6 +272,12 @@
         ->OnSearchResultContainerResultsChanged();
   }
 
+  void SimulateQuery(const std::u16string& query) {
+    view()->search_box()->InsertText(
+        u"test",
+        ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText);
+  }
+
   // Overridden from SearchBoxViewDelegate:
   void QueryChanged(SearchBoxViewBase* sender) override {}
   void AssistantButtonPressed() override {}
@@ -314,9 +321,10 @@
 
 // Tests that the close button is still visible after the search box is
 // activated (in zero state).
-TEST_P(SearchBoxViewTest, CloseButtonIVisibleInZeroStateSearchBox) {
+TEST_P(SearchBoxViewTest, CloseButtonVisibleInZeroStateSearchBox) {
   SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED);
-  EXPECT_TRUE(view()->close_button()->GetVisible());
+  EXPECT_EQ(!IsProductivityLauncherEnabled(),
+            view()->close_button()->GetVisible());
 }
 
 // Tests that the search box is inactive by default.
@@ -406,8 +414,7 @@
 // Tests that traversing search results is disabled while results are being
 // updated.
 TEST_P(SearchBoxViewTest, ChangeSelectionWhileResultsAreChanging) {
-  SetSearchBoxActive(true, ui::ET_UNKNOWN);
-  view()->search_box()->SetText(u"test");
+  SimulateQuery(u"test");
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, u"tester",
                      std::u16string());
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, u"testing",
@@ -452,8 +459,8 @@
 // Tests that traversing search results is disabled while the result that would
 // be selected next is being removed from results.
 TEST_P(SearchBoxViewTest, ChangeSelectionWhileResultsAreBeingRemoved) {
-  SetSearchBoxActive(true, ui::ET_UNKNOWN);
-  view()->search_box()->SetText(u"test");
+  SimulateQuery(u"test");
+
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, u"tester",
                      std::u16string());
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, u"testing",
@@ -494,8 +501,7 @@
 }
 
 TEST_P(SearchBoxViewTest, UserSelectionNotOverridenByNewResults) {
-  SetSearchBoxActive(true, ui::ET_UNKNOWN);
-  view()->search_box()->SetText(u"test");
+  SimulateQuery(u"test");
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, u"tester",
                      std::u16string());
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, u"testing",
@@ -563,8 +569,7 @@
 
 TEST_P(SearchBoxViewTest,
        UserSelectionInNonDefaultContainerNotOverridenByNewResults) {
-  SetSearchBoxActive(true, ui::ET_UNKNOWN);
-  view()->search_box()->SetText(u"test");
+  SimulateQuery(u"test");
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, u"tester",
                      std::u16string());
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, u"testing",
@@ -641,8 +646,7 @@
 // Tests that the default selection is reset after resetting and reactivating
 // the search box.
 TEST_P(SearchBoxViewTest, ResetSelectionAfterResettingSearchBox) {
-  SetSearchBoxActive(true, ui::ET_UNKNOWN);
-  view()->search_box()->SetText(u"test");
+  SimulateQuery(u"test");
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, u"test1",
                      std::u16string());
   CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, u"test2",
@@ -926,7 +930,8 @@
 
   // Assistant button is not showing up under zero state.
   KeyPress(ui::VKEY_BACK);
-  EXPECT_FALSE(view()->assistant_button()->GetVisible());
+  EXPECT_EQ(IsProductivityLauncherEnabled(),
+            view()->assistant_button()->GetVisible());
 }
 
 class SearchBoxViewAutocompleteTest : public SearchBoxViewTest {
diff --git a/ash/components/disks/disk_mount_manager.cc b/ash/components/disks/disk_mount_manager.cc
index e7423c3..d20118a 100644
--- a/ash/components/disks/disk_mount_manager.cc
+++ b/ash/components/disks/disk_mount_manager.cc
@@ -111,8 +111,7 @@
     if (type == MountType::kDevice) {
       DiskMap::const_iterator it = disks_.find(source_path);
       if (it == disks_.end() || it->second->is_hidden()) {
-        OnMountCompleted(
-            MountEntry(MountError::kInternal, source_path, type, ""));
+        OnMountCompleted({MountError::kInternal, source_path, type});
         return;
       }
     }
@@ -384,8 +383,7 @@
     if (result)
       return;
 
-    OnMountCompleted(
-        MountEntry(MountError::kInternal, source_path, type, std::string()));
+    OnMountCompleted({MountError::kInternal, source_path, type});
   }
 
   void RemountRemovableDrive(const Disk& disk, MountAccessMode access_mode) {
@@ -395,9 +393,8 @@
       // Not in mount_points_. This happens when the mount_points and disks_ are
       // inconsistent.
       LOG(ERROR) << "Cannot find mount point '" << mount_path << "'";
-      OnMountCompleted(MountEntry(MountError::kPathNotMounted,
-                                  disk.device_path(), MountType::kDevice,
-                                  mount_path));
+      OnMountCompleted({MountError::kPathNotMounted, disk.device_path(),
+                        MountType::kDevice, mount_path});
       return;
     }
     const std::string& source_path = mount_point->second.source_path;
@@ -463,33 +460,33 @@
 
   // CrosDisksClient::Observer override.
   void OnMountCompleted(const MountEntry& entry) override {
-    auto iter = deferred_mount_events_.find(entry.source_path());
+    auto iter = deferred_mount_events_.find(entry.source_path);
     if (iter != deferred_mount_events_.end()) {
       iter->second.push_back(entry);
       return;
     }
 
     MountCondition mount_condition = MOUNT_CONDITION_NONE;
-    if (entry.mount_type() == MountType::kDevice) {
-      if (entry.error_code() == MountError::kUnknownFilesystem) {
+    if (entry.mount_type == MountType::kDevice) {
+      if (entry.error_code == MountError::kUnknownFilesystem) {
         mount_condition = MOUNT_CONDITION_UNKNOWN_FILESYSTEM;
       }
-      if (entry.error_code() == MountError::kUnsupportedFilesystem) {
+      if (entry.error_code == MountError::kUnsupportedFilesystem) {
         mount_condition = MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM;
       }
     }
-    const MountPointInfo mount_info(entry.source_path(), entry.mount_path(),
-                                    entry.mount_type(), mount_condition);
+
+    const MountPointInfo mount_info(entry.source_path, entry.mount_path,
+                                    entry.mount_type, mount_condition);
 
     // If the device is corrupted but it's still possible to format it, it will
     // be fake mounted.
-    if (entry.error_code() == MountError::kNone || mount_info.mount_condition) {
+    if (entry.error_code == MountError::kNone || mount_info.mount_condition) {
       mount_points_.emplace(mount_info.mount_path, mount_info);
     }
 
     Disk* disk = nullptr;
-    if ((entry.error_code() == MountError::kNone ||
-         mount_info.mount_condition) &&
+    if ((entry.error_code == MountError::kNone || mount_info.mount_condition) &&
         mount_info.mount_type == MountType::kDevice &&
         !mount_info.source_path.empty() && !mount_info.mount_path.empty()) {
       DiskMap::iterator disk_map_iter = disks_.find(mount_info.source_path);
@@ -502,7 +499,7 @@
         // |source_path| should be same as |disk->device_path| because
         // |VolumeManager::OnDiskEvent()| passes the latter to cros-disks as a
         // source path when mounting a device.
-        AccessModeMap::iterator it = access_modes_.find(entry.source_path());
+        AccessModeMap::iterator it = access_modes_.find(entry.source_path);
 
         // Store whether the disk was mounted in read-only mode due to a policy.
         disk->set_write_disabled_by_policy(
@@ -516,17 +513,17 @@
         // non-trivial.
         // TODO(amistry): Change these code paths to use device path instead of
         // mount path.
-        disk->set_mounted(entry.error_code() == MountError::kNone);
+        disk->set_mounted(entry.error_code == MountError::kNone);
       }
     }
     // Observers may read the values of disks_. So notify them after tweaking
     // values of disks_.
-    auto it = mount_callbacks_.find(entry.source_path());
+    auto it = mount_callbacks_.find(entry.source_path);
     if (it != mount_callbacks_.end()) {
-      std::move(it->second).Run(entry.error_code(), mount_info);
+      std::move(it->second).Run(entry.error_code, mount_info);
       mount_callbacks_.erase(it);
     }
-    NotifyMountStatusUpdate(MOUNTING, entry.error_code(), mount_info);
+    NotifyMountStatusUpdate(MOUNTING, entry.error_code, mount_info);
 
     if (disk) {
       disk->set_is_first_mount(false);
diff --git a/ash/components/drivefs/BUILD.gn b/ash/components/drivefs/BUILD.gn
index 2f3871e..a6a736293 100644
--- a/ash/components/drivefs/BUILD.gn
+++ b/ash/components/drivefs/BUILD.gn
@@ -64,6 +64,7 @@
     "//chromeos/ash/components/dbus/cros_disks",
     "//chromeos/dbus:test_support",
     "//net",
+    "//testing/gmock",
   ]
 }
 
diff --git a/ash/components/drivefs/fake_drivefs.cc b/ash/components/drivefs/fake_drivefs.cc
index 6ec2496..526b16ecc 100644
--- a/ash/components/drivefs/fake_drivefs.cc
+++ b/ash/components/drivefs/fake_drivefs.cc
@@ -566,11 +566,6 @@
   std::move(callback).Run(drive::FileError::FILE_ERROR_OK);
 }
 
-void FakeDriveFs::GetSyncingPaths(
-    drivefs::mojom::DriveFs::GetSyncingPathsCallback callback) {
-  std::move(callback).Run(drive::FILE_ERROR_OK, syncing_paths_);
-}
-
 void FakeDriveFs::PollHostedFilePinStates() {}
 
 }  // namespace drivefs
diff --git a/ash/components/drivefs/fake_drivefs.h b/ash/components/drivefs/fake_drivefs.h
index a115252..ee4a098 100644
--- a/ash/components/drivefs/fake_drivefs.h
+++ b/ash/components/drivefs/fake_drivefs.h
@@ -19,6 +19,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace drivefs {
 
@@ -73,6 +74,11 @@
     return delegate_;
   }
 
+  MOCK_METHOD(void,
+              GetSyncingPaths,
+              (drivefs::mojom::DriveFs::GetSyncingPathsCallback callback),
+              (override));
+
   const base::FilePath& mount_path() { return mount_path_; }
 
  private:
@@ -157,9 +163,6 @@
       drivefs::mojom::MirrorPathStatus status,
       drivefs::mojom::DriveFs::ToggleSyncForPathCallback callback) override;
 
-  void GetSyncingPaths(
-      drivefs::mojom::DriveFs::GetSyncingPathsCallback callback) override;
-
   void PollHostedFilePinStates() override;
 
   const base::FilePath mount_path_;
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc
index 7cb7a90..0f248724 100644
--- a/ash/search_box/search_box_view_base.cc
+++ b/ash/search_box/search_box_view_base.cc
@@ -39,6 +39,7 @@
 #include "ui/views/layout/box_layout_view.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/layout_provider.h"
+#include "ui/views/view_class_properties.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -365,6 +366,10 @@
   base::WeakPtrFactory<SearchIconImageView> weak_factory_{this};
 };
 
+SearchBoxViewBase::InitParams::InitParams() = default;
+
+SearchBoxViewBase::InitParams::~InitParams() = default;
+
 SearchBoxViewBase::SearchBoxViewBase(SearchBoxViewDelegate* delegate)
     : delegate_(delegate), search_box_(new SearchBoxTextfield(this)) {
   DCHECK(delegate_);
@@ -459,19 +464,6 @@
       content_container_->AddChildView(std::make_unique<views::View>());
   search_box_button_container_->SetLayoutManager(
       std::make_unique<views::FillLayout>());
-
-  assistant_button_ = search_box_button_container_->AddChildView(
-      std::make_unique<SearchBoxImageButton>(
-          base::BindRepeating(&SearchBoxViewDelegate::AssistantButtonPressed,
-                              base::Unretained(delegate_))));
-  assistant_button_->SetFlipCanvasOnPaintForRTLUI(false);
-  // Default hidden, child class should decide if it should shown.
-  assistant_button_->SetVisible(false);
-
-  close_button_ = search_box_button_container_->AddChildView(
-      std::make_unique<SearchBoxImageButton>(
-          base::BindRepeating(&SearchBoxViewDelegate::CloseButtonPressed,
-                              base::Unretained(delegate_))));
 }
 
 SearchBoxViewBase::~SearchBoxViewBase() = default;
@@ -487,15 +479,36 @@
         kSearchBoxBorderCornerRadius,
         AppListColorProvider::Get()->GetSearchBoxBackgroundColor()));
   }
+
   if (params.increase_child_view_padding) {
     content_container_->SetBetweenChildSpacing(kInnerPadding);
   }
 
+  if (params.textfield_margins) {
+    search_box()->SetProperty(views::kMarginsKey, *params.textfield_margins);
+  }
+
   UpdateSearchBoxBorder();
   UpdatePlaceholderTextStyle();
-  SetupAssistantButton();
   SetupBackButton();
-  SetupCloseButton();
+}
+
+views::ImageButton* SearchBoxViewBase::CreateCloseButton(
+    const base::RepeatingClosure& button_callback) {
+  DCHECK(!close_button_);
+  close_button_ = search_box_button_container_->AddChildView(
+      std::make_unique<SearchBoxImageButton>(button_callback));
+  close_button_->SetVisible(false);
+  return close_button_;
+}
+
+views::ImageButton* SearchBoxViewBase::CreateAssistantButton(
+    const base::RepeatingClosure& button_callback) {
+  DCHECK(!assistant_button_);
+  assistant_button_ = search_box_button_container_->AddChildView(
+      std::make_unique<SearchBoxImageButton>(button_callback));
+  assistant_button_->SetVisible(false);
+  return assistant_button_;
 }
 
 bool SearchBoxViewBase::HasSearch() const {
@@ -556,13 +569,9 @@
     return;
 
   is_search_box_active_ = active;
-  UpdateSearchIcon();
   UpdatePlaceholderTextStyle();
   search_box_->SetCursorEnabled(active);
 
-  // Clear ghost text when toggling search box active state.
-  MaybeSetAutocompleteGhostText(std::u16string(), std::u16string());
-
   if (active) {
     search_box_->RequestFocus();
     RecordSearchBoxActivationHistogram(event_type);
@@ -609,10 +618,6 @@
   return "SearchBoxView";
 }
 
-void SearchBoxViewBase::OnKeyEvent(ui::KeyEvent* event) {
-  delegate_->OnSearchBoxKeyEvent(event);
-}
-
 void SearchBoxViewBase::OnGestureEvent(ui::GestureEvent* event) {
   HandleSearchBoxEvent(event);
 }
@@ -689,13 +694,11 @@
 }
 
 void SearchBoxViewBase::UpdateButtonsVisibility() {
-  DCHECK(close_button_ && assistant_button_);
+  DCHECK(close_button_);
 
   const bool should_show_close_button =
       !search_box_->GetText().empty() ||
       (show_close_button_when_active_ && is_search_box_active_);
-  const bool should_show_assistant_button =
-      show_assistant_button_ && !should_show_close_button;
 
   if (should_show_close_button) {
     MaybeFadeButtonIn(close_button_);
@@ -703,10 +706,14 @@
     MaybeFadeButtonOut(close_button_);
   }
 
-  if (should_show_assistant_button) {
-    MaybeFadeButtonIn(assistant_button_);
-  } else {
-    MaybeFadeButtonOut(assistant_button_);
+  if (assistant_button_) {
+    const bool should_show_assistant_button =
+        show_assistant_button_ && !should_show_close_button;
+    if (should_show_assistant_button) {
+      MaybeFadeButtonIn(assistant_button_);
+    } else {
+      MaybeFadeButtonOut(assistant_button_);
+    }
   }
 }
 
@@ -787,6 +794,7 @@
 }
 
 void SearchBoxViewBase::SetShowAssistantButton(bool show) {
+  DCHECK(assistant_button_);
   show_assistant_button_ = show;
   UpdateButtonsVisibility();
 }
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h
index c56c1c2e..5861b20 100644
--- a/ash/search_box/search_box_view_base.h
+++ b/ash/search_box/search_box_view_base.h
@@ -10,7 +10,9 @@
 
 #include "ash/search_box/search_box_constants.h"
 #include "base/bind.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/types/event_type.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
@@ -29,8 +31,8 @@
 
 namespace ash {
 
-class SearchBoxViewDelegate;
 class SearchBoxImageButton;
+class SearchBoxViewDelegate;
 class SearchIconImageView;
 
 // These are used in histograms, do not remove/renumber entries. If you're
@@ -57,21 +59,20 @@
 
   ~SearchBoxViewBase() override;
 
-  struct InitParams {
-    // Whether to show close button if the search box is active and empty.
-    bool show_close_button_when_active = false;
+  // Creates the search box close button at the right edge of the search box.
+  // The close button will initially be hidden. The visibility will be updated
+  // appropriatelly when `UpdateButtonsVisibility()` gets called.
+  views::ImageButton* CreateCloseButton(
+      const base::RepeatingClosure& button_callback);
 
-    // Whether to create a rounded-rect background.
-    bool create_background = true;
-
-    // Whether to animate the transition when the search icon is changed.
-    bool animate_changing_search_icon = false;
-
-    // Whether we should increase spacing between `search_icon_', 'search_box_',
-    // and the 'search_box_button_container_'.
-    bool increase_child_view_padding = false;
-  };
-  virtual void Init(const InitParams& params);
+  // Creates the search box assistant button at the right edge of the search
+  // box. Note that the assistant button will only be shown if close button is
+  // hidden, as the buttons have the same expected position within the search
+  // box.
+  // The assistant button will initially be hidden. The visibility will be
+  // updated appropriatelly when `UpdateButtonsVisibility()` gets called.
+  views::ImageButton* CreateAssistantButton(
+      const base::RepeatingClosure& button_callback);
 
   bool HasSearch() const;
 
@@ -106,7 +107,6 @@
   // Overridden from views::View:
   gfx::Size CalculatePreferredSize() const override;
   const char* GetClassName() const override;
-  void OnKeyEvent(ui::KeyEvent* event) override;
   void OnGestureEvent(ui::GestureEvent* event) override;
   void OnMouseEvent(ui::MouseEvent* event) override;
   void OnThemeChanged() override;
@@ -137,6 +137,31 @@
   virtual void UpdateSearchBoxFocusPaint();
 
  protected:
+  struct InitParams {
+    InitParams();
+    ~InitParams();
+    InitParams(const InitParams&) = delete;
+    InitParams& operator=(const InitParams&) = delete;
+
+    // Whether to show close button if the search box is active and empty.
+    bool show_close_button_when_active = false;
+
+    // Whether to create a rounded-rect background.
+    bool create_background = true;
+
+    // Whether to animate the transition when the search icon is changed.
+    bool animate_changing_search_icon = false;
+
+    // Whether we should increase spacing between `search_icon_', 'search_box_',
+    // and the 'search_box_button_container_'.
+    bool increase_child_view_padding = false;
+
+    // If set, the margins that should be used for the search box text field.
+    absl::optional<gfx::Insets> textfield_margins;
+  };
+
+  void Init(const InitParams& params);
+
   // Fires query change notification.
   void NotifyQueryChanged();
 
@@ -164,6 +189,7 @@
                           const ui::GestureEvent& gesture_event) override;
 
   SearchBoxViewDelegate* delegate() { return delegate_; }
+
   views::BoxLayoutView* box_layout_view() { return content_container_; }
 
   void SetSearchBoxBackgroundCornerRadius(int corner_radius);
@@ -185,9 +211,6 @@
   // Updates model text and selection model with current Textfield info.
   virtual void UpdateModel(bool initiated_by_user) {}
 
-  // Updates the search icon.
-  virtual void UpdateSearchIcon() {}
-
   // Updates the color and alignment of the placeholder text.
   virtual void UpdatePlaceholderTextStyle() {}
 
@@ -195,8 +218,6 @@
   virtual void UpdateSearchBoxBorder() {}
 
   // Setup button's image, accessible name, and tooltip text etc.
-  virtual void SetupAssistantButton() {}
-  virtual void SetupCloseButton() {}
   virtual void SetupBackButton() {}
 
   // Records in histograms the activation of the searchbox.
diff --git a/ash/services/device_sync/cryptauth_device_manager_impl.cc b/ash/services/device_sync/cryptauth_device_manager_impl.cc
index 10d94f9..88915a0 100644
--- a/ash/services/device_sync/cryptauth_device_manager_impl.cc
+++ b/ash/services/device_sync/cryptauth_device_manager_impl.cc
@@ -707,7 +707,7 @@
 
   bool unlock_keys_changed =
       devices_as_list !=
-      *pref_service_->GetList(prefs::kCryptAuthDeviceSyncUnlockKeys);
+      pref_service_->GetValueList(prefs::kCryptAuthDeviceSyncUnlockKeys);
   {
     ListPrefUpdate update(pref_service_, prefs::kCryptAuthDeviceSyncUnlockKeys);
     *update.Get() = std::move(devices_as_list);
diff --git a/ash/services/device_sync/cryptauth_enrollment_manager_impl.cc b/ash/services/device_sync/cryptauth_enrollment_manager_impl.cc
index 0e86dac..9b511f16 100644
--- a/ash/services/device_sync/cryptauth_enrollment_manager_impl.cc
+++ b/ash/services/device_sync/cryptauth_enrollment_manager_impl.cc
@@ -220,7 +220,7 @@
 
 std::string CryptAuthEnrollmentManagerImpl::GetUserPublicKey() const {
   absl::optional<std::string> public_key = util::DecodeFromValueString(
-      pref_service_->Get(prefs::kCryptAuthEnrollmentUserPublicKey));
+      &pref_service_->GetValue(prefs::kCryptAuthEnrollmentUserPublicKey));
   if (!public_key) {
     PA_LOG(ERROR) << "Invalid public key stored in user prefs.";
     return std::string();
@@ -231,7 +231,7 @@
 
 std::string CryptAuthEnrollmentManagerImpl::GetUserPrivateKey() const {
   absl::optional<std::string> private_key = util::DecodeFromValueString(
-      pref_service_->Get(prefs::kCryptAuthEnrollmentUserPrivateKey));
+      &pref_service_->GetValue(prefs::kCryptAuthEnrollmentUserPrivateKey));
   if (!private_key) {
     PA_LOG(ERROR) << "Invalid private key stored in user prefs.";
     return std::string();
diff --git a/ash/services/device_sync/cryptauth_scheduler_impl.cc b/ash/services/device_sync/cryptauth_scheduler_impl.cc
index b11a159..083ec5c 100644
--- a/ash/services/device_sync/cryptauth_scheduler_impl.cc
+++ b/ash/services/device_sync/cryptauth_scheduler_impl.cc
@@ -71,14 +71,14 @@
 
 cryptauthv2::ClientDirective BuildClientDirective(PrefService* pref_service) {
   DCHECK(pref_service);
-  const base::Value* encoded_client_directive =
-      pref_service->Get(prefs::kCryptAuthSchedulerClientDirective);
-  if (encoded_client_directive->GetString() == kNoClientDirective)
+  const base::Value& encoded_client_directive =
+      pref_service->GetValue(prefs::kCryptAuthSchedulerClientDirective);
+  if (encoded_client_directive.GetString() == kNoClientDirective)
     return CreateDefaultClientDirective();
 
   absl::optional<cryptauthv2::ClientDirective> client_directive_from_pref =
       util::DecodeProtoMessageFromValueString<cryptauthv2::ClientDirective>(
-          encoded_client_directive);
+          &encoded_client_directive);
 
   return client_directive_from_pref.value_or(CreateDefaultClientDirective());
 }
diff --git a/ash/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc b/ash/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc
index 1fbb21a..b887105 100644
--- a/ash/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc
+++ b/ash/services/device_sync/cryptauth_v2_enrollment_manager_impl.cc
@@ -389,7 +389,7 @@
 
 std::string CryptAuthV2EnrollmentManagerImpl::GetV1UserPublicKey() const {
   absl::optional<std::string> public_key = util::DecodeFromValueString(
-      pref_service_->Get(prefs::kCryptAuthEnrollmentUserPublicKey));
+      &pref_service_->GetValue(prefs::kCryptAuthEnrollmentUserPublicKey));
   if (!public_key) {
     PA_LOG(ERROR) << "Invalid public key stored in user prefs.";
     return std::string();
@@ -400,7 +400,7 @@
 
 std::string CryptAuthV2EnrollmentManagerImpl::GetV1UserPrivateKey() const {
   absl::optional<std::string> private_key = util::DecodeFromValueString(
-      pref_service_->Get(prefs::kCryptAuthEnrollmentUserPrivateKey));
+      &pref_service_->GetValue(prefs::kCryptAuthEnrollmentUserPrivateKey));
   if (!private_key) {
     PA_LOG(ERROR) << "Invalid private key stored in user prefs.";
     return std::string();
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc
index 6f9a8a3..ca4d2335 100644
--- a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc
+++ b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -400,12 +400,6 @@
   search_box_view_->SetSearchBoxActive(false, ui::ET_UNKNOWN);
 }
 
-void KeyboardShortcutView::CloseButtonPressed() {
-  // After clicking search box close button focus the search box text field.
-  search_box_view_->search_box()->RequestFocus();
-  search_box_view_->ClearSearch();
-}
-
 void KeyboardShortcutView::ActiveChanged(ash::SearchBoxViewBase* sender) {
   const bool is_search_box_active = sender->is_search_box_active();
   is_search_box_empty_ = sender->IsSearchBoxTrimmedQueryEmpty();
@@ -434,10 +428,7 @@
   TRACE_EVENT0("shortcut_viewer", "InitViews");
   // Init search box view.
   auto search_box_view = std::make_unique<KSVSearchBoxView>(this);
-  ash::SearchBoxViewBase::InitParams params;
-  params.show_close_button_when_active = false;
-  params.create_background = true;
-  search_box_view->Init(params);
+  search_box_view->Initialize();
   search_box_view_ = AddChildView(std::move(search_box_view));
 
   // Init no search result illustration view.
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_view.h b/ash/shortcut_viewer/views/keyboard_shortcut_view.h
index 81d14d69..b45ab3c 100644
--- a/ash/shortcut_viewer/views/keyboard_shortcut_view.h
+++ b/ash/shortcut_viewer/views/keyboard_shortcut_view.h
@@ -61,7 +61,7 @@
   void QueryChanged(ash::SearchBoxViewBase* sender) override;
   void AssistantButtonPressed() override {}
   void BackButtonPressed() override;
-  void CloseButtonPressed() override;
+  void CloseButtonPressed() override {}
   void ActiveChanged(ash::SearchBoxViewBase* sender) override;
   void OnSearchBoxKeyEvent(ui::KeyEvent* event) override {}
   bool CanSelectSearchResults() override;
diff --git a/ash/shortcut_viewer/views/ksv_search_box_view.cc b/ash/shortcut_viewer/views/ksv_search_box_view.cc
index d797cb86..d0966fc 100644
--- a/ash/shortcut_viewer/views/ksv_search_box_view.cc
+++ b/ash/shortcut_viewer/views/ksv_search_box_view.cc
@@ -47,6 +47,24 @@
   search_box()->SetAccessibleName(search_box_name);
   SetSearchIconImage(
       gfx::CreateVectorIcon(ash::kKsvSearchBarIcon, GetPrimaryIconColor()));
+
+  views::ImageButton* close_button = CreateCloseButton(base::BindRepeating(
+      &KSVSearchBoxView::CloseButtonPressed, base::Unretained(this)));
+  close_button->SetHasInkDropActionOnClick(true);
+  close_button->SetPreferredSize(gfx::Size(kIconSize, kIconSize));
+  close_button->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
+  close_button->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
+  const std::u16string close_button_label(
+      l10n_util::GetStringUTF16(IDS_KSV_CLEAR_SEARCHBOX_ACCESSIBILITY_NAME));
+  close_button->SetAccessibleName(close_button_label);
+  close_button->SetTooltipText(close_button_label);
+}
+
+void KSVSearchBoxView::Initialize() {
+  ash::SearchBoxViewBase::InitParams params;
+  params.show_close_button_when_active = false;
+  params.create_background = true;
+  Init(params);
 }
 
 gfx::Size KSVSearchBoxView::CalculatePreferredSize() const {
@@ -114,22 +132,6 @@
   UpdateBackgroundColor(GetBackgroundColor());
 }
 
-void KSVSearchBoxView::SetupCloseButton() {
-  views::ImageButton* close = close_button();
-  close->SetHasInkDropActionOnClick(true);
-  close->SetImage(
-      views::ImageButton::STATE_NORMAL,
-      gfx::CreateVectorIcon(ash::kKsvSearchCloseIcon, GetCloseButtonColor()));
-  close->SetPreferredSize(gfx::Size(kIconSize, kIconSize));
-  close->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
-  close->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
-  const std::u16string close_button_label(
-      l10n_util::GetStringUTF16(IDS_KSV_CLEAR_SEARCHBOX_ACCESSIBILITY_NAME));
-  close->SetAccessibleName(close_button_label);
-  close->SetTooltipText(close_button_label);
-  close->SetVisible(false);
-}
-
 void KSVSearchBoxView::SetupBackButton() {
   views::ImageButton* back = back_button();
   back->SetHasInkDropActionOnClick(true);
@@ -157,6 +159,12 @@
                           : gfx::Canvas::TEXT_ALIGN_LEFT);
 }
 
+void KSVSearchBoxView::CloseButtonPressed() {
+  // After clicking search box close button focus the search box text field.
+  search_box()->RequestFocus();
+  ClearSearch();
+}
+
 SkColor KSVSearchBoxView::GetBackgroundColor() {
   constexpr SkColor kBackgroundDarkColor =
       SkColorSetARGB(0xFF, 0x32, 0x33, 0x34);
diff --git a/ash/shortcut_viewer/views/ksv_search_box_view.h b/ash/shortcut_viewer/views/ksv_search_box_view.h
index d6884b3..d70ed32 100644
--- a/ash/shortcut_viewer/views/ksv_search_box_view.h
+++ b/ash/shortcut_viewer/views/ksv_search_box_view.h
@@ -26,6 +26,9 @@
 
   ~KSVSearchBoxView() override = default;
 
+  // Initializes the search box view style.
+  void Initialize();
+
   // views::View:
   gfx::Size CalculatePreferredSize() const override;
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
@@ -36,13 +39,15 @@
 
   // SearchBoxViewBase:
   void UpdateSearchBoxBorder() override;
-  void SetupCloseButton() override;
   void SetupBackButton() override;
   void UpdatePlaceholderTextStyle() override;
 
  private:
   void SetPlaceholderTextAttributes();
 
+  // Callback for press on the search box close button.
+  void CloseButtonPressed();
+
   SkColor GetBackgroundColor();
   SkColor GetBackButtonColor();
   SkColor GetBorderColor();
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc
index 7b74c44..21f26a6 100644
--- a/ash/style/ash_color_provider.cc
+++ b/ash/style/ash_color_provider.cc
@@ -225,11 +225,6 @@
                                       IsDarkModeEnabled());
 }
 
-SkColor AshColorProvider::GetBackgroundColorInMode(bool use_dark_color) const {
-  return cros_styles::ResolveColor(cros_styles::ColorName::kBgColor,
-                                   use_dark_color);
-}
-
 SkColor AshColorProvider::GetContentLayerColorImpl(ContentLayerType type,
                                                    bool use_dark_color) const {
   switch (type) {
@@ -298,11 +293,7 @@
 }
 
 SkColor AshColorProvider::GetBackgroundDefaultColor() const {
-  return GetBackgroundColorInMode(IsDarkModeEnabled());
-}
-
-SkColor AshColorProvider::GetInvertedBackgroundDefaultColor() const {
-  return GetBackgroundColorInMode(!IsDarkModeEnabled());
+  return IsDarkModeEnabled() ? gfx::kGoogleGrey900 : SK_ColorWHITE;
 }
 
 SkColor AshColorProvider::GetBackgroundThemedColorImpl(
diff --git a/ash/style/ash_color_provider.h b/ash/style/ash_color_provider.h
index e42cb44..3300db3 100644
--- a/ash/style/ash_color_provider.h
+++ b/ash/style/ash_color_provider.h
@@ -59,8 +59,6 @@
   // color will be different based on color mode and color theme (see
   // |is_themed_|).
   SkColor GetBackgroundColor() const;
-  // Gets the background color in the desired color mode dark/light.
-  SkColor GetBackgroundColorInMode(bool use_dark_color) const;
 
  private:
   // Gets the color of |type| of the corresponding layer. Returns the color on
@@ -70,8 +68,6 @@
 
   // Gets the background default color based on the current color mode.
   SkColor GetBackgroundDefaultColor() const;
-  // Gets the background default color based on the current inverted color mode.
-  SkColor GetInvertedBackgroundDefaultColor() const;
 
   // Gets the background themed color that's calculated based on the color
   // extracted from wallpaper. For dark mode, it will be dark muted wallpaper
diff --git a/ash/webui/os_feedback_ui/resources/help_content.html b/ash/webui/os_feedback_ui/resources/help_content.html
index dd6605d..c079f73 100644
--- a/ash/webui/os_feedback_ui/resources/help_content.html
+++ b/ash/webui/os_feedback_ui/resources/help_content.html
@@ -47,11 +47,10 @@
   }
 
   #helpContentIcon {
-    display: inline-block;
-    height: 20px;
     --iron-icon-fill-color: var(--cros-icon-color-secondary);
+    --iron-icon-height: 20px;
+    --iron-icon-width: 20px;
     margin-inline-start: 6px;
-    width: 20px;
   }
 </style>
 <iron-media-query query="(prefers-color-scheme: dark)"
@@ -60,12 +59,13 @@
 <div id="helpContentContainer">
   <div id="helpContentLabelContainer">
     <h2 class="help-content-label">[[getLabel_(searchResult, isOnline_)]]</h2>
-    <iron-icon icon="help-content:info" id="helpContentIcon">
+    <iron-icon icon="help-content:info" id="helpContentIcon"
+        hidden$="[[!hasSuggestedHelpContent_(searchResult, isOnline_)]]">
     </iron-icon>
   </div>
   <template is="dom-if" if="[[!isOnline_]]">
     <div class="help-content-offline-details">
-      <img src="[[getOfflineIllustrationSrc_(isDarkModeEnabled_)]]" 
+      <img src="[[getOfflineIllustrationSrc_(isDarkModeEnabled_)]]"
            alt="[[i18n('helpContentOfflineAltText')]]">
       <div class="help-content-offline-text">
         [[i18n('helpContentOfflineMessage')]]
@@ -77,9 +77,9 @@
       <template>
         <div class="help-item">
           <a href="[[getUrl_(item)]]" target="_blank">
-            <iron-icon 
-              icon="[[getIcon_(item.contentType)]]" 
-              class="help-item-icon"></iron-icon>
+            <iron-icon icon="[[getIcon_(item.contentType)]]"
+                class="help-item-icon">
+            </iron-icon>
             <span>[[getTitle_(item)]]</span>
           </a>
         </div>
diff --git a/ash/webui/os_feedback_ui/resources/help_content.js b/ash/webui/os_feedback_ui/resources/help_content.js
index 71646c2b74..f648aaa4 100644
--- a/ash/webui/os_feedback_ui/resources/help_content.js
+++ b/ash/webui/os_feedback_ui/resources/help_content.js
@@ -93,24 +93,32 @@
 
   /**
    * Compute the label to use.
-   * @param {!SearchResult} searchResult
-   * @returns {string}
+   * @return {string}
    * @protected
    */
-  getLabel_(searchResult) {
+  getLabel_() {
     if (!this.isOnline_) {
       return this.i18n('popularHelpContent');
     }
-    if (!searchResult.isPopularContent) {
+    if (!this.searchResult.isPopularContent) {
       return this.i18n('suggestedHelpContent');
     }
-    if (searchResult.isQueryEmpty) {
+    if (this.searchResult.isQueryEmpty) {
       return this.i18n('popularHelpContent');
     }
     return this.i18n('noMatchedResults');
   }
 
   /**
+   * Returns true if there are suggested help content displayed.
+   * @return {boolean}
+   * @protected
+   */
+  hasSuggestedHelpContent_() {
+    return (this.isOnline_ && !this.searchResult.isPopularContent);
+  }
+
+  /**
    * Find the icon name to be used for a help content type.
    * @param {!HelpContentType} contentType
    * @return {string}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index d92045b..53e3296 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -693,6 +693,8 @@
     "task/common/checked_lock.h",
     "task/common/checked_lock_impl.cc",
     "task/common/checked_lock_impl.h",
+    "task/common/lazy_now.cc",
+    "task/common/lazy_now.h",
     "task/common/operations_controller.cc",
     "task/common/operations_controller.h",
     "task/common/scoped_defer_task_posting.cc",
@@ -727,8 +729,6 @@
     "task/sequence_manager/fence.cc",
     "task/sequence_manager/fence.h",
     "task/sequence_manager/lazily_deallocated_deque.h",
-    "task/sequence_manager/lazy_now.cc",
-    "task/sequence_manager/lazy_now.h",
     "task/sequence_manager/sequence_manager.cc",
     "task/sequence_manager/sequence_manager.h",
     "task/sequence_manager/sequence_manager_impl.cc",
@@ -2366,8 +2366,6 @@
   if (enable_base_tracing) {
     sources += [
       "trace_event/auto_open_close_event.h",
-      "trace_event/blame_context.cc",
-      "trace_event/blame_context.h",
       "trace_event/builtin_categories.cc",
       "trace_event/builtin_categories.h",
       "trace_event/category_registry.cc",
@@ -3886,7 +3884,6 @@
   if (enable_base_tracing) {
     sources += [
       "test/trace_event_analyzer_unittest.cc",
-      "trace_event/blame_context_unittest.cc",
       "trace_event/event_name_filter_unittest.cc",
       "trace_event/heap_profiler_allocation_context_tracker_unittest.cc",
       "trace_event/memory_allocator_dump_unittest.cc",
diff --git a/base/profiler/thread_delegate_posix.cc b/base/profiler/thread_delegate_posix.cc
index 1bb76bdb..d184b16 100644
--- a/base/profiler/thread_delegate_posix.cc
+++ b/base/profiler/thread_delegate_posix.cc
@@ -17,6 +17,10 @@
 #include "base/files/scoped_file.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS)
+extern "C" void* __libc_stack_end;
+#endif
+
 namespace base {
 
 namespace {
@@ -54,19 +58,23 @@
 
 absl::optional<uintptr_t> GetThreadStackBaseAddress(
     SamplingProfilerThreadToken thread_token) {
-#if BUILDFLAG(IS_ANDROID)
-  // The implementation of pthread_getattr_np() in Bionic reads proc/self/maps
-  // to find the main thread base address, and throws SIGABRT when it fails to
-  // read or parse the file. So, try to read the maps to get the main thread
-  // stack base and cache the result. Other thread base addresses are sourced
-  // from pthread state so are cheap to get.
   const bool is_main_thread = thread_token.id == GetCurrentProcId();
   if (is_main_thread) {
+#if BUILDFLAG(IS_ANDROID)
+    // The implementation of pthread_getattr_np() in Bionic reads proc/self/maps
+    // to find the main thread base address, and throws SIGABRT when it fails to
+    // read or parse the file. So, try to read the maps to get the main thread
+    // stack base and cache the result. Other thread base addresses are sourced
+    // from pthread state so are cheap to get.
     static const absl::optional<uintptr_t> main_thread_base_address =
         GetAndroidMainThreadStackBaseAddressImpl();
     return main_thread_base_address;
-  }
+#elif BUILDFLAG(IS_CHROMEOS)
+    // Similarly, the sandbox will prevent pthread_getattr_np() from working
+    // on the main thread in ChromeOS. Here, we have a simpler solution.
+    return reinterpret_cast<uintptr_t>(__libc_stack_end);
 #endif
+  }
   return GetThreadStackBaseAddressImpl(thread_token);
 }
 
diff --git a/base/profiler/thread_delegate_posix_unittest.cc b/base/profiler/thread_delegate_posix_unittest.cc
index 4d1597b..e996e96 100644
--- a/base/profiler/thread_delegate_posix_unittest.cc
+++ b/base/profiler/thread_delegate_posix_unittest.cc
@@ -29,9 +29,9 @@
   EXPECT_LE(base, ClampAdd(stack_addr, 4 * 1024 * 1024));
 }
 
-#if BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
 
-TEST(ThreadDelegatePosixTest, AndroidMainThreadStackBase) {
+TEST(ThreadDelegatePosixTest, MainThreadStackBase) {
   // The delegate does not use pthread id for main thread.
   auto delegate = ThreadDelegatePosix::Create(
       SamplingProfilerThreadToken{GetCurrentProcId(), pthread_t()});
diff --git a/base/task/sequence_manager/lazy_now.cc b/base/task/common/lazy_now.cc
similarity index 90%
rename from base/task/sequence_manager/lazy_now.cc
rename to base/task/common/lazy_now.cc
index f4e8d16..0cb7335 100644
--- a/base/task/sequence_manager/lazy_now.cc
+++ b/base/task/common/lazy_now.cc
@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 
 #include "base/check.h"
 #include "base/time/tick_clock.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
-namespace sequence_manager {
 
 LazyNow::LazyNow(TimeTicks now) : now_(now), tick_clock_(nullptr) {}
 
@@ -38,5 +37,4 @@
   return *now_;
 }
 
-}  // namespace sequence_manager
 }  // namespace base
diff --git a/base/task/sequence_manager/lazy_now.h b/base/task/common/lazy_now.h
similarity index 86%
rename from base/task/sequence_manager/lazy_now.h
rename to base/task/common/lazy_now.h
index 269cb96..4a41f11 100644
--- a/base/task/sequence_manager/lazy_now.h
+++ b/base/task/common/lazy_now.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_TASK_SEQUENCE_MANAGER_LAZY_NOW_H_
-#define BASE_TASK_SEQUENCE_MANAGER_LAZY_NOW_H_
+#ifndef BASE_TASK_COMMON_LAZY_NOW_H_
+#define BASE_TASK_COMMON_LAZY_NOW_H_
 
 #include "base/base_export.h"
 #include "base/memory/raw_ptr_exclusion.h"
@@ -14,8 +14,6 @@
 
 class TickClock;
 
-namespace sequence_manager {
-
 // Now() is somewhat expensive so it makes sense not to call Now() unless we
 // really need to and to avoid subsequent calls if already called once.
 // LazyNow objects are expected to be short-living to represent accurate time.
@@ -42,7 +40,6 @@
   RAW_PTR_EXCLUSION const TickClock* tick_clock_;  // Not owned.
 };
 
-}  // namespace sequence_manager
 }  // namespace base
 
-#endif  // BASE_TASK_SEQUENCE_MANAGER_LAZY_NOW_H_
+#endif  // BASE_TASK_COMMON_LAZY_NOW_H_
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
index d69c5335..00f7fab2 100644
--- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc
+++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -3225,34 +3225,6 @@
   EXPECT_EQ(nullptr, sequence_manager()->currently_executing_task_queue());
 }
 
-#if BUILDFLAG(ENABLE_BASE_TRACING)
-TEST_P(SequenceManagerTest, BlameContextAttribution) {
-  if (GetUnderlyingRunnerType() == RunnerType::kMessagePump)
-    return;
-  using trace_analyzer::Query;
-
-  auto queue = CreateTaskQueue();
-
-  trace_analyzer::Start("*");
-  {
-    trace_event::BlameContext blame_context("base", "name", "type", "scope", 0,
-                                            nullptr);
-    blame_context.Initialize();
-    queue->SetBlameContext(&blame_context);
-    queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
-    RunLoop().RunUntilIdle();
-  }
-  auto analyzer = trace_analyzer::Stop();
-
-  trace_analyzer::TraceEventVector events;
-  Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
-            Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
-  analyzer->FindEvents(q, &events);
-
-  EXPECT_EQ(2u, events.size());
-}
-#endif  // BUILDFLAG(ENABLE_BASE_TRACING)
-
 TEST_P(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasks) {
   auto queue = CreateTaskQueue();
 
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h
index 4c4ce1b..e4f37ee 100644
--- a/base/task/sequence_manager/sequenced_task_source.h
+++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -8,7 +8,7 @@
 #include "base/base_export.h"
 #include "base/callback_helpers.h"
 #include "base/pending_task.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/tasks.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/base/task/sequence_manager/task_queue.cc b/base/task/sequence_manager/task_queue.cc
index c54c76ee..6b71fd2 100644
--- a/base/task/sequence_manager/task_queue.cc
+++ b/base/task/sequence_manager/task_queue.cc
@@ -180,7 +180,6 @@
     TakeTaskQueueImpl().reset();
     return;
   }
-  impl_->SetBlameContext(nullptr);
   sequence_manager_->UnregisterTaskQueueImpl(TakeTaskQueueImpl());
 }
 
@@ -272,13 +271,6 @@
   impl_->RemoveTaskObserver(task_observer);
 }
 
-void TaskQueue::SetBlameContext(trace_event::BlameContext* blame_context) {
-  DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
-  if (!impl_)
-    return;
-  impl_->SetBlameContext(blame_context);
-}
-
 void TaskQueue::InsertFence(InsertFencePosition position) {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   if (!impl_)
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h
index 2f0528d3..ea6c820b 100644
--- a/base/task/sequence_manager/task_queue.h
+++ b/base/task/sequence_manager/task_queue.h
@@ -11,7 +11,7 @@
 #include "base/check.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/common/checked_lock.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/tasks.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/task_observer.h"
@@ -28,10 +28,6 @@
 
 class TaskObserver;
 
-namespace trace_event {
-class BlameContext;
-}
-
 namespace sequence_manager {
 
 namespace internal {
@@ -302,11 +298,6 @@
   void AddTaskObserver(TaskObserver* task_observer);
   void RemoveTaskObserver(TaskObserver* task_observer);
 
-  // Set the blame context which is entered and left while executing tasks from
-  // this task queue. |blame_context| must be null or outlive this task queue.
-  // Must be called on the thread this TaskQueue was created by.
-  void SetBlameContext(trace_event::BlameContext* blame_context);
-
   enum class InsertFencePosition {
     kNow,  // Tasks posted on the queue up till this point further may run.
            // All further tasks are blocked.
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc
index 3cbdf53..48a6187 100644
--- a/base/task/sequence_manager/task_queue_impl.cc
+++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -936,9 +936,6 @@
                                           bool was_blocked_or_low_priority) {
   DCHECK(should_notify_observers_);
 
-  if (main_thread_only().blame_context)
-    main_thread_only().blame_context->Enter();
-
   for (auto& observer : main_thread_only().task_observers)
     observer.WillProcessTask(task, was_blocked_or_low_priority);
 }
@@ -947,12 +944,6 @@
   DCHECK(should_notify_observers_);
   for (auto& observer : main_thread_only().task_observers)
     observer.DidProcessTask(task);
-  if (main_thread_only().blame_context)
-    main_thread_only().blame_context->Leave();
-}
-
-void TaskQueueImpl::SetBlameContext(trace_event::BlameContext* blame_context) {
-  main_thread_only().blame_context = blame_context;
 }
 
 void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) {
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h
index c0590b2a..436b259 100644
--- a/base/task/sequence_manager/task_queue_impl.h
+++ b/base/task/sequence_manager/task_queue_impl.h
@@ -40,11 +40,8 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
-namespace sequence_manager {
-
 class LazyNow;
-
-namespace internal {
+namespace sequence_manager::internal {
 
 class SequenceManagerImpl;
 class WorkQueue;
@@ -144,7 +141,6 @@
   TaskQueue::QueuePriority GetQueuePriority() const;
   void AddTaskObserver(TaskObserver* task_observer);
   void RemoveTaskObserver(TaskObserver* task_observer);
-  void SetBlameContext(trace_event::BlameContext* blame_context);
   void InsertFence(TaskQueue::InsertFencePosition position);
   void InsertFenceAt(TimeTicks time);
   void RemoveFence();
@@ -437,7 +433,6 @@
     ObserverList<TaskObserver>::Unchecked task_observers;
     HeapHandle heap_handle;
     bool is_enabled = true;
-    raw_ptr<trace_event::BlameContext> blame_context = nullptr;  // Not owned.
     absl::optional<Fence> current_fence;
     absl::optional<TimeTicks> delayed_fence;
     // Snapshots the next sequence number when the queue is unblocked, otherwise
@@ -630,8 +625,7 @@
   const bool delayed_fence_allowed_;
 };
 
-}  // namespace internal
-}  // namespace sequence_manager
+}  // namespace sequence_manager::internal
 }  // namespace base
 
 #endif  // BASE_TASK_SEQUENCE_MANAGER_TASK_QUEUE_IMPL_H_
diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h
index 3667a91..cd54685 100644
--- a/base/task/sequence_manager/thread_controller.h
+++ b/base/task/sequence_manager/thread_controller.h
@@ -15,8 +15,8 @@
 #include "base/message_loop/message_pump.h"
 #include "base/profiler/sample_metadata.h"
 #include "base/run_loop.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/associated_thread_id.h"
-#include "base/task/sequence_manager/lazy_now.h"
 #include "base/task/sequence_manager/tasks.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/thread_annotations.h"
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc
index 2b3d7897..6f0e2ea 100644
--- a/base/task/sequence_manager/thread_controller_impl.cc
+++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -11,7 +11,7 @@
 #include "base/message_loop/message_pump.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/task/sequence_manager/sequenced_task_source.h"
 #include "base/trace_event/base_tracing.h"
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h
index b4a5bd7..717b818 100644
--- a/base/task/sequence_manager/time_domain.h
+++ b/base/task/sequence_manager/time_domain.h
@@ -7,7 +7,7 @@
 
 #include "base/base_export.h"
 #include "base/check.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/tasks.h"
 #include "base/time/tick_clock.h"
 #include "base/values.h"
diff --git a/base/task/sequence_manager/wake_up_queue.h b/base/task/sequence_manager/wake_up_queue.h
index 4f0bc47..0c025de 100644
--- a/base/task/sequence_manager/wake_up_queue.h
+++ b/base/task/sequence_manager/wake_up_queue.h
@@ -9,7 +9,7 @@
 #include "base/check.h"
 #include "base/containers/intrusive_heap.h"
 #include "base/memory/raw_ptr.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/time/time.h"
 #include "base/values.h"
diff --git a/base/task/sequence_manager/work_queue_unittest.cc b/base/task/sequence_manager/work_queue_unittest.cc
index 46a99ca8..712e8aa 100644
--- a/base/task/sequence_manager/work_queue_unittest.cc
+++ b/base/task/sequence_manager/work_queue_unittest.cc
@@ -8,9 +8,9 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/enqueue_order.h"
 #include "base/task/sequence_manager/fence.h"
-#include "base/task/sequence_manager/lazy_now.h"
 #include "base/task/sequence_manager/sequence_manager.h"
 #include "base/task/sequence_manager/task_order.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index 055d350..434a174 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -23,6 +23,7 @@
 #include "base/run_loop.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/task/sequence_manager/time_domain.h"
 #include "base/task/simple_task_executor.h"
@@ -728,7 +729,7 @@
   // ReclaimMemory sweeps canceled delayed tasks.
   sequence_manager_->ReclaimMemory();
   DCHECK(mock_time_domain_);
-  sequence_manager::LazyNow lazy_now(mock_time_domain_->NowTicks());
+  LazyNow lazy_now(mock_time_domain_->NowTicks());
   if (!sequence_manager_->IsIdleForTesting())
     return TimeDelta();
   absl::optional<sequence_manager::WakeUp> wake_up =
diff --git a/base/trace_event/base_tracing.h b/base/trace_event/base_tracing.h
index 6fe702e..e8c72ea 100644
--- a/base/trace_event/base_tracing.h
+++ b/base/trace_event/base_tracing.h
@@ -15,7 +15,6 @@
 #if BUILDFLAG(ENABLE_BASE_TRACING)
 // Update the check in //base/PRESUBMIT.py when adding new headers here.
 // TODO(crbug/1006541): Switch to perfetto for trace event implementation.
-#include "base/trace_event/blame_context.h"               // nogncheck
 #include "base/trace_event/heap_profiler.h"               // nogncheck
 #include "base/trace_event/interned_args_helper.h"        // nogncheck
 #include "base/trace_event/memory_allocator_dump_guid.h"  // nogncheck
diff --git a/base/trace_event/base_tracing_forward.h b/base/trace_event/base_tracing_forward.h
index 677966b8..6d68c2e 100644
--- a/base/trace_event/base_tracing_forward.h
+++ b/base/trace_event/base_tracing_forward.h
@@ -37,7 +37,6 @@
 namespace base {
 namespace trace_event {
 
-class BlameContext;
 class ConvertableToTraceFormat;
 class TracedValue;
 
diff --git a/base/trace_event/blame_context.cc b/base/trace_event/blame_context.cc
deleted file mode 100644
index d2d0e3e3..0000000
--- a/base/trace_event/blame_context.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/trace_event/blame_context.h"
-
-#include <cstring>
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/traced_value.h"
-#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
-
-namespace base {
-namespace trace_event {
-
-BlameContext::BlameContext(const char* category,
-                           const char* name,
-                           const char* type,
-                           const char* scope,
-                           uint64_t id,
-                           const BlameContext* parent_context)
-    : category_(category),
-      name_(name),
-      type_(type),
-      scope_(scope),
-      id_(id),
-      parent_scope_(parent_context ? parent_context->scope() : nullptr),
-      parent_id_(parent_context ? parent_context->id() : 0),
-      category_group_enabled_(nullptr) {
-  DCHECK(!parent_context || !std::strcmp(name_, parent_context->name()))
-      << "Parent blame context must have the same name";
-}
-
-BlameContext::~BlameContext() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(WasInitialized());
-  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_DELETE_OBJECT,
-                                  category_group_enabled_, type_, scope_, id_,
-                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
-  trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this);
-}
-
-void BlameContext::Enter() {
-  DCHECK(WasInitialized());
-  if (LIKELY(!*category_group_enabled_))
-    return;
-  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_ENTER_CONTEXT,
-                                  category_group_enabled_, name_, scope_, id_,
-                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
-}
-
-void BlameContext::Leave() {
-  DCHECK(WasInitialized());
-  if (LIKELY(!*category_group_enabled_))
-    return;
-  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_LEAVE_CONTEXT,
-                                  category_group_enabled_, name_, scope_, id_,
-                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
-}
-
-void BlameContext::TakeSnapshot() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(WasInitialized());
-  if (LIKELY(!*category_group_enabled_))
-    return;
-  std::unique_ptr<trace_event::TracedValue> snapshot(
-      new trace_event::TracedValue);
-  AsValueInto(snapshot.get());
-  TraceArguments args("snapshot", std::move(snapshot));
-  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT,
-                                  category_group_enabled_, type_, scope_, id_,
-                                  &args, TRACE_EVENT_FLAG_HAS_ID);
-}
-
-void BlameContext::OnTraceLogEnabled() {
-  DCHECK(WasInitialized());
-  TakeSnapshot();
-}
-
-void BlameContext::OnTraceLogDisabled() {}
-
-void BlameContext::AsValueInto(trace_event::TracedValue* state) {
-  DCHECK(WasInitialized());
-  if (!parent_id_)
-    return;
-  state->BeginDictionary("parent");
-  state->SetString("id_ref", StringPrintf("0x%" PRIx64, parent_id_));
-  state->SetString("scope", parent_scope_);
-  state->EndDictionary();
-}
-
-void BlameContext::WriteIntoTrace(perfetto::TracedValue context) const {
-  auto dict = std::move(context).WriteDictionary();
-  dict.Add("id", id_);
-  dict.Add("parent_id", parent_id_);
-  dict.Add("scope", scope_);
-}
-
-void BlameContext::Initialize() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  category_group_enabled_ =
-      TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_);
-  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_CREATE_OBJECT,
-                                  category_group_enabled_, type_, scope_, id_,
-                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
-  trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
-      weak_factory_.GetWeakPtr());
-  TakeSnapshot();
-}
-
-bool BlameContext::WasInitialized() const {
-  return category_group_enabled_ != nullptr;
-}
-
-}  // namespace trace_event
-}  // namespace base
diff --git a/base/trace_event/blame_context.h b/base/trace_event/blame_context.h
deleted file mode 100644
index f65b677..0000000
--- a/base/trace_event/blame_context.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_TRACE_EVENT_BLAME_CONTEXT_H_
-#define BASE_TRACE_EVENT_BLAME_CONTEXT_H_
-
-#include <inttypes.h>
-
-#include "base/base_export.h"
-#include "base/threading/thread_checker.h"
-#include "base/trace_event/trace_log.h"
-#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-
-namespace trace_event {
-
-// A blame context represents a logical unit to which we want to attribute
-// different costs (e.g., CPU, network, or memory usage). An example of a blame
-// context is an <iframe> element on a web page. Different subsystems can
-// "enter" and "leave" blame contexts to indicate that they are doing work which
-// should be accounted against this blame context.
-//
-// A blame context can optionally have a parent context, forming a blame context
-// tree. When work is attributed to a particular blame context, it is considered
-// to count against all of that context's children too. This is useful when work
-// cannot be exactly attributed into a more specific context. For example,
-// Javascript garbage collection generally needs to inspect all objects on a
-// page instead looking at each <iframe> individually. In this case the work
-// should be attributed to a blame context which is the parent of all <iframe>
-// blame contexts.
-class BASE_EXPORT BlameContext
-    : public trace_event::TraceLog::AsyncEnabledStateObserver {
- public:
-  // Construct a blame context belonging to the blame context tree |name|, using
-  // the tracing category |category|, identified by |id| from the |scope|
-  // namespace. |type| identifies the type of this object snapshot in the blame
-  // context tree. |parent_context| is the parent of this blame context or
-  // null. Note that all strings must have application lifetime.
-  //
-  // For example, a blame context which represents a specific <iframe> in a
-  // browser frame tree could be specified with:
-  //
-  //   category="blink",
-  //   name="FrameTree",
-  //   type="IFrame",
-  //   scope="IFrameIdentifier",
-  //   id=1234.
-  //
-  // Each <iframe> blame context could have another <iframe> context as a
-  // parent, or a top-level context which represents the entire browser:
-  //
-  //   category="blink",
-  //   name="FrameTree",
-  //   type="Browser",
-  //   scope="BrowserIdentifier",
-  //   id=1.
-  //
-  // Note that the |name| property is identical, signifying that both context
-  // types are part of the same tree.
-  //
-  BlameContext(const char* category,
-               const char* name,
-               const char* type,
-               const char* scope,
-               uint64_t id,
-               const BlameContext* parent_context);
-
-  BlameContext(const BlameContext&) = delete;
-  BlameContext& operator=(const BlameContext&) = delete;
-
-  ~BlameContext() override;
-
-  // Initialize the blame context, automatically taking a snapshot if tracing is
-  // enabled. Must be called before any other methods on this class.
-  void Initialize();
-
-  // Indicate that the current thread is now doing work which should count
-  // against this blame context.  This function is allowed to be called in a
-  // thread different from where the blame context was created; However, any
-  // client doing that must be fully responsible for ensuring thready safety.
-  void Enter();
-
-  // Leave and stop doing work for a previously entered blame context. If
-  // another blame context belonging to the same tree was entered prior to this
-  // one, it becomes the active blame context for this thread again.  Similar
-  // to Enter(), this function can be called in a thread different from where
-  // the blame context was created, and the same requirement on thread safety
-  // must be satisfied.
-  void Leave();
-
-  // Record a snapshot of the blame context. This is normally only needed if a
-  // blame context subclass defines custom properties (see AsValueInto) and one
-  // or more of those properties have changed.
-  void TakeSnapshot();
-
-  const char* category() const { return category_; }
-  const char* name() const { return name_; }
-  const char* type() const { return type_; }
-  const char* scope() const { return scope_; }
-  uint64_t id() const { return id_; }
-
-  // trace_event::TraceLog::EnabledStateObserver implementation:
-  void OnTraceLogEnabled() override;
-  void OnTraceLogDisabled() override;
-
-  void WriteIntoTrace(perfetto::TracedValue context) const;
-
- protected:
-  // Serialize the properties of this blame context into |state|. Subclasses can
-  // override this method to record additional properties (e.g, the URL for an
-  // <iframe> blame context). Note that an overridden implementation must still
-  // call this base method.
-  // TODO(altimin): Replace all users with WriteIntoTrace and remove it.
-  virtual void AsValueInto(trace_event::TracedValue* state);
-
- private:
-  bool WasInitialized() const;
-
-  // The following string pointers have application lifetime.
-  const char* category_;
-  const char* name_;
-  const char* type_;
-  const char* scope_;
-  const uint64_t id_;
-
-  const char* parent_scope_;
-  const uint64_t parent_id_;
-
-  const unsigned char* category_group_enabled_;
-
-  ThreadChecker thread_checker_;
-  WeakPtrFactory<BlameContext> weak_factory_{this};
-};
-
-}  // namespace trace_event
-}  // namespace base
-
-#endif  // BASE_TRACE_EVENT_BLAME_CONTEXT_H_
diff --git a/base/trace_event/blame_context_unittest.cc b/base/trace_event/blame_context_unittest.cc
deleted file mode 100644
index 5b1372f..0000000
--- a/base/trace_event/blame_context_unittest.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/trace_event/blame_context.h"
-
-#include "base/json/json_writer.h"
-#include "base/test/task_environment.h"
-#include "base/test/trace_event_analyzer.h"
-#include "base/trace_event/traced_value.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-namespace trace_event {
-namespace {
-
-const char kTestBlameContextCategory[] = "base";
-const char kDisabledTestBlameContextCategory[] = "disabled-by-default-base";
-const char kTestBlameContextName[] = "TestBlameContext";
-const char kTestBlameContextType[] = "TestBlameContextType";
-const char kTestBlameContextScope[] = "TestBlameContextScope";
-
-class TestBlameContext : public BlameContext {
- public:
-  explicit TestBlameContext(int id)
-      : BlameContext(kTestBlameContextCategory,
-                     kTestBlameContextName,
-                     kTestBlameContextType,
-                     kTestBlameContextScope,
-                     id,
-                     nullptr) {}
-
-  TestBlameContext(int id, const TestBlameContext& parent)
-      : BlameContext(kTestBlameContextCategory,
-                     kTestBlameContextName,
-                     kTestBlameContextType,
-                     kTestBlameContextScope,
-                     id,
-                     &parent) {}
-
- protected:
-  void AsValueInto(trace_event::TracedValue* state) override {
-    BlameContext::AsValueInto(state);
-    state->SetBoolean("crossStreams", false);
-  }
-};
-
-class DisabledTestBlameContext : public BlameContext {
- public:
-  explicit DisabledTestBlameContext(int id)
-      : BlameContext(kDisabledTestBlameContextCategory,
-                     kTestBlameContextName,
-                     kTestBlameContextType,
-                     kTestBlameContextScope,
-                     id,
-                     nullptr) {}
-};
-
-class BlameContextTest : public testing::Test {
- protected:
-  test::TaskEnvironment task_environment_;
-};
-
-TEST_F(BlameContextTest, EnterAndLeave) {
-  using trace_analyzer::Query;
-  trace_analyzer::Start("*");
-  {
-    TestBlameContext blame_context(0x1234);
-    blame_context.Initialize();
-    blame_context.Enter();
-    blame_context.Leave();
-  }
-  auto analyzer = trace_analyzer::Stop();
-
-  trace_analyzer::TraceEventVector events;
-  Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
-            Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
-  analyzer->FindEvents(q, &events);
-
-  EXPECT_EQ(2u, events.size());
-  EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
-  EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
-  EXPECT_EQ(kTestBlameContextName, events[0]->name);
-  EXPECT_EQ("0x1234", events[0]->id);
-  EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
-  EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
-  EXPECT_EQ(kTestBlameContextName, events[1]->name);
-  EXPECT_EQ("0x1234", events[1]->id);
-}
-
-TEST_F(BlameContextTest, DifferentCategories) {
-  // Ensure there is no cross talk between blame contexts from different
-  // categories.
-  using trace_analyzer::Query;
-  trace_analyzer::Start("*");
-  {
-    TestBlameContext blame_context(0x1234);
-    DisabledTestBlameContext disabled_blame_context(0x5678);
-    blame_context.Initialize();
-    blame_context.Enter();
-    blame_context.Leave();
-    disabled_blame_context.Initialize();
-    disabled_blame_context.Enter();
-    disabled_blame_context.Leave();
-  }
-  auto analyzer = trace_analyzer::Stop();
-
-  trace_analyzer::TraceEventVector events;
-  Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
-            Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
-  analyzer->FindEvents(q, &events);
-
-  // None of the events from the disabled-by-default category should show up.
-  EXPECT_EQ(2u, events.size());
-  EXPECT_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, events[0]->phase);
-  EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
-  EXPECT_EQ(kTestBlameContextName, events[0]->name);
-  EXPECT_EQ("0x1234", events[0]->id);
-  EXPECT_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, events[1]->phase);
-  EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
-  EXPECT_EQ(kTestBlameContextName, events[1]->name);
-  EXPECT_EQ("0x1234", events[1]->id);
-}
-
-TEST_F(BlameContextTest, TakeSnapshot) {
-  using trace_analyzer::Query;
-  trace_analyzer::Start("*");
-  {
-    TestBlameContext parent_blame_context(0x5678);
-    TestBlameContext blame_context(0x1234, parent_blame_context);
-    parent_blame_context.Initialize();
-    blame_context.Initialize();
-    blame_context.TakeSnapshot();
-  }
-  auto analyzer = trace_analyzer::Stop();
-
-  trace_analyzer::TraceEventVector events;
-  Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT);
-  analyzer->FindEvents(q, &events);
-
-  // We should have 3 snapshots: one for both calls to Initialize() and one from
-  // the explicit call to TakeSnapshot().
-  EXPECT_EQ(3u, events.size());
-  EXPECT_EQ(kTestBlameContextCategory, events[0]->category);
-  EXPECT_EQ(kTestBlameContextType, events[0]->name);
-  EXPECT_EQ("0x5678", events[0]->id);
-  EXPECT_TRUE(events[0]->HasDictArg("snapshot"));
-
-  EXPECT_EQ(kTestBlameContextCategory, events[1]->category);
-  EXPECT_EQ(kTestBlameContextType, events[1]->name);
-  EXPECT_EQ("0x1234", events[1]->id);
-  EXPECT_TRUE(events[0]->HasDictArg("snapshot"));
-
-  EXPECT_EQ(kTestBlameContextCategory, events[2]->category);
-  EXPECT_EQ(kTestBlameContextType, events[2]->name);
-  EXPECT_EQ("0x1234", events[2]->id);
-  EXPECT_TRUE(events[0]->HasDictArg("snapshot"));
-
-  const char kExpectedSnapshotJson[] =
-      "{"
-          "\"crossStreams\":false,"
-          "\"parent\":{"
-              "\"id_ref\":\"0x5678\","
-              "\"scope\":\"TestBlameContextScope\""
-          "}"
-      "}";
-
-  std::string snapshot_json;
-  JSONWriter::Write(events[2]->GetKnownArgAsDict("snapshot"), &snapshot_json);
-  EXPECT_EQ(kExpectedSnapshotJson, snapshot_json);
-}
-
-}  // namepace
-}  // namespace trace_event
-}  // namespace base
diff --git a/base/trace_event/trace_event_stub.h b/base/trace_event/trace_event_stub.h
index bd79d13..479052f 100644
--- a/base/trace_event/trace_event_stub.h
+++ b/base/trace_event/trace_event_stub.h
@@ -135,27 +135,6 @@
   std::string ToFormattedJSON() const { return ""; }
 };
 
-class BASE_EXPORT BlameContext {
- public:
-  BlameContext(const char* category,
-               const char* name,
-               const char* type,
-               const char* scope,
-               int64_t id,
-               const BlameContext* parent_context) {}
-
-  void Initialize() {}
-  void Enter() {}
-  void Leave() {}
-  void TakeSnapshot() {}
-
-  const char* category() const { return nullptr; }
-  const char* name() const { return nullptr; }
-  const char* type() const { return nullptr; }
-  const char* scope() const { return nullptr; }
-  int64_t id() const { return 0; }
-};
-
 struct MemoryDumpArgs;
 class ProcessMemoryDump;
 
diff --git a/base/values.cc b/base/values.cc
index d0d3ce2..a45a70d 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1656,18 +1656,6 @@
   return is_string;
 }
 
-bool DictionaryValue::GetString(StringPiece path,
-                                std::u16string* out_value) const {
-  const Value* value;
-  if (!Get(path, &value))
-    return false;
-
-  const bool is_string = value->is_string();
-  if (is_string && out_value)
-    *out_value = UTF8ToUTF16(value->GetString());
-  return is_string;
-}
-
 bool DictionaryValue::GetDictionary(StringPiece path,
                                     const DictionaryValue** out_value) const {
   const Value* value;
@@ -1726,10 +1714,6 @@
 
 DictionaryValue::Iterator::~Iterator() = default;
 
-DictionaryValue* DictionaryValue::DeepCopy() const {
-  return new DictionaryValue(dict());
-}
-
 std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
   return std::make_unique<DictionaryValue>(dict());
 }
diff --git a/base/values.h b/base/values.h
index 0c37db302..3c0ee7b 100644
--- a/base/values.h
+++ b/base/values.h
@@ -1341,7 +1341,6 @@
   // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
   // otherwise.
   bool GetString(StringPiece path, std::string* out_value) const;
-  bool GetString(StringPiece path, std::u16string* out_value) const;
   // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
   // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
   // otherwise.
@@ -1384,9 +1383,6 @@
 
   // DEPRECATED, use `Value::Dict::Clone()` instead.
   // TODO(crbug.com/646113): Delete this and migrate callsites.
-  DictionaryValue* DeepCopy() const;
-  // DEPRECATED, use `Value::Dict::Clone()` instead.
-  // TODO(crbug.com/646113): Delete this and migrate callsites.
   std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
 };
 
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 1a24c2f1..51861891 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -2346,23 +2346,6 @@
   EXPECT_FALSE(main_dict.GetString("list", static_cast<std::string*>(nullptr)));
   EXPECT_FALSE(main_dict.GetString("DNE", static_cast<std::string*>(nullptr)));
 
-  EXPECT_FALSE(
-      main_dict.GetString("bool", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("int", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("double", static_cast<std::u16string*>(nullptr)));
-  EXPECT_TRUE(
-      main_dict.GetString("string", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("binary", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("dict", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("list", static_cast<std::u16string*>(nullptr)));
-  EXPECT_FALSE(
-      main_dict.GetString("DNE", static_cast<std::u16string*>(nullptr)));
-
   EXPECT_FALSE(main_dict.GetDictionary("bool", nullptr));
   EXPECT_FALSE(main_dict.GetDictionary("int", nullptr));
   EXPECT_FALSE(main_dict.GetDictionary("double", nullptr));
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
index 1921f43..25084c4 100644
--- a/base/win/shortcut.cc
+++ b/base/win/shortcut.cc
@@ -6,7 +6,6 @@
 
 #include <objbase.h>
 #include <propkey.h>
-#include <shellapi.h>
 #include <shlobj.h>
 #include <wrl/client.h>
 
@@ -364,27 +363,5 @@
   return true;
 }
 
-bool CanPinShortcutToTaskbar() {
-  // "Pin to taskbar" stopped being supported in Windows 10.
-  return GetVersion() < Version::WIN10;
-}
-
-bool PinShortcutToTaskbar(const FilePath& shortcut) {
-  ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
-  DCHECK(CanPinShortcutToTaskbar());
-
-  intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
-      nullptr, L"taskbarpin", shortcut.value().c_str(), nullptr, nullptr, 0));
-  return result > 32;
-}
-
-bool UnpinShortcutFromTaskbar(const FilePath& shortcut) {
-  ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
-
-  intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
-      nullptr, L"taskbarunpin", shortcut.value().c_str(), nullptr, nullptr, 0));
-  return result > 32;
-}
-
 }  // namespace win
 }  // namespace base
diff --git a/base/win/shortcut.h b/base/win/shortcut.h
index 646f217..63d998f5 100644
--- a/base/win/shortcut.h
+++ b/base/win/shortcut.h
@@ -152,20 +152,6 @@
                                  FilePath* target_path,
                                  std::wstring* args);
 
-// Pin to taskbar is only supported on Windows 7 and Windows 8. Returns true on
-// those platforms.
-BASE_EXPORT bool CanPinShortcutToTaskbar();
-
-// Pins a shortcut to the taskbar on Windows 7 and 8. The |shortcut| file must
-// already exist and be a shortcut that points to an executable. The app id of
-// the shortcut is used to group windows and must be set correctly.
-BASE_EXPORT bool PinShortcutToTaskbar(const FilePath& shortcut);
-
-// Unpins a shortcut from the Windows 7+ taskbar. The |shortcut| must exist and
-// already be pinned to the taskbar. The app id of the shortcut is used as the
-// identifier for the taskbar item to remove and must be set correctly.
-BASE_EXPORT bool UnpinShortcutFromTaskbar(const FilePath& shortcut);
-
 }  // namespace win
 }  // namespace base
 
diff --git a/build/fuchsia/common.py b/build/fuchsia/common.py
index c81c745..f102b46d 100644
--- a/build/fuchsia/common.py
+++ b/build/fuchsia/common.py
@@ -153,7 +153,7 @@
     timeout_timer.cancel()
 
   if process.returncode == -9:
-    raise Exception('Timeout when executing \"%s\".' % ' '.join(command))
+    raise TimeoutError('Timeout when executing \"%s\".' % ' '.join(command))
 
   return process.returncode, out, err
 
diff --git a/build/fuchsia/device_target.py b/build/fuchsia/device_target.py
index af2766c..95dcf88 100644
--- a/build/fuchsia/device_target.py
+++ b/build/fuchsia/device_target.py
@@ -404,10 +404,13 @@
     if self._node_name:
       pave_command.extend(['-n', self._node_name, '-1'])
     logging.info(' '.join(pave_command))
-    return_code, stdout, stderr = SubprocessCallWithTimeout(pave_command,
-                                                            timeout_secs=300)
-    if return_code != 0:
-      raise ProvisionDeviceException('Could not pave device.')
+    try:
+      return_code, stdout, stderr = SubprocessCallWithTimeout(pave_command,
+                                                              timeout_secs=300)
+      if return_code != 0:
+        raise ProvisionDeviceException('Could not pave device.')
+    except TimeoutError as ex:
+      raise ProvisionDeviceException('Timed out while paving device.') from ex
     self._ParseNodename(stderr)
 
   def Restart(self):
diff --git a/build/util/version.py b/build/util/version.py
index 5667a65..eb5e1f63 100755
--- a/build/util/version.py
+++ b/build/util/version.py
@@ -26,9 +26,10 @@
 
   The file must exist, otherwise you get the Python exception from open().
   """
-  for line in open(file_name, 'r').readlines():
-    key, val = line.rstrip('\r\n').split('=', 1)
-    values_dict[key] = val
+  with open(file_name, 'r') as f:
+    for line in f.readlines():
+      key, val = line.rstrip('\r\n').split('=', 1)
+      values_dict[key] = val
 
 
 def FetchValues(file_list, is_official_build=None):
diff --git a/cc/metrics/compositor_frame_reporter.cc b/cc/metrics/compositor_frame_reporter.cc
index a0f56642..8293311 100644
--- a/cc/metrics/compositor_frame_reporter.cc
+++ b/cc/metrics/compositor_frame_reporter.cc
@@ -1317,7 +1317,15 @@
   // TODO(crbug.com/1334827): Explore calculating predictions for multiple
   // events. Currently only kGestureScrollUpdate event predictions
   // are being calculated, consider including other stages in future changes.
-  auto& event_metrics = events_metrics_.front();
+  auto event_it = std::find_if(
+      events_metrics_.begin(), events_metrics_.end(),
+      [](const std::unique_ptr<EventMetrics>& event) {
+        return event &&
+               event->type() == EventMetrics::EventType::kGestureScrollUpdate;
+      });
+  if (event_it == events_metrics_.end())
+    return;
+  auto& event_metrics = *event_it;
 
   base::TimeTicks dispatch_start_time =
       event_metrics->GetDispatchStageTimestamp(
diff --git a/cc/metrics/compositor_frame_reporter_unittest.cc b/cc/metrics/compositor_frame_reporter_unittest.cc
index 013b9b3..c39286d6 100644
--- a/cc/metrics/compositor_frame_reporter_unittest.cc
+++ b/cc/metrics/compositor_frame_reporter_unittest.cc
@@ -1287,5 +1287,112 @@
   pipeline_reporter_ = nullptr;
 }
 
+// Tests that when a frame is presented to the user, event latency predictions
+// are reported properly for filtered EventTypes.
+TEST_F(CompositorFrameReporterTest, EventLatencyMultipleEventTypePredictions) {
+  std::vector<int> dispatch_times = {300, 300, 300, 300, 300};
+  // The prediction should only be updated with the ScrollUpdateType event,
+  // other EventType metrics should be ignored.
+  std::unique_ptr<EventMetrics> event_metrics_ptrs[] = {
+      CreateEventMetrics(ui::ET_TOUCH_PRESSED),
+      CreateEventMetrics(ui::ET_TOUCH_MOVED),
+      CreateScrollUpdateEventMetricsWithDispatchTimes(
+          false, ScrollUpdateEventMetrics::ScrollUpdateType::kContinued,
+          dispatch_times),
+      CreateEventMetrics(ui::ET_TOUCH_MOVED)};
+  // The last ET_TOUCH_MOVED event above adds 12 us to transition time.
+  const base::TimeDelta kTouchEventTransition = base::Microseconds(12);
+  EXPECT_THAT(event_metrics_ptrs, Each(NotNull()));
+  EventMetrics::List events_metrics = {
+      std::make_move_iterator(std::begin(event_metrics_ptrs)),
+      std::make_move_iterator(std::end(event_metrics_ptrs))};
+
+  AdvanceNowByUs(300);
+  // Total transition time is 312 us because of the extra 3 us from the
+  // ET_TOUCH_MOVED event.
+  pipeline_reporter_->StartStage(
+      CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame,
+      Now());
+
+  // For this test there are only 3 compositor substages updated which reflects
+  // a more realistic scenario.
+
+  AdvanceNowByUs(300);  // kBeginImplFrameToSendBeginMainFrame duration
+  pipeline_reporter_->StartStage(
+      CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame,
+      Now());
+
+  AdvanceNowByUs(300);  // kEndActivateToSubmitCompositorFrame duration
+  pipeline_reporter_->StartStage(
+      CompositorFrameReporter::StageType::
+          kSubmitCompositorFrameToPresentationCompositorFrame,
+      Now());
+
+  // kSubmitCompositorFrameToPresentationCompositorFrame duration
+  AdvanceNowByUs(300);
+  pipeline_reporter_->TerminateFrame(
+      CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
+
+  pipeline_reporter_->AddEventsMetrics(std::move(events_metrics));
+
+  // Test with no previous stage predictions.
+  std::vector<base::TimeDelta> expected_dispatch1(kNumDispatchStages,
+                                                  base::Microseconds(-1));
+  IntToTimeDeltaVector(expected_dispatch1,
+                       std::vector<int>{300, 300, 300, 300, 300});
+  base::TimeDelta expected_transition1 =
+      base::Microseconds(300) + kTouchEventTransition;
+  std::vector<base::TimeDelta> expected_compositor1(kNumOfStages,
+                                                    base::Microseconds(-1));
+  IntToTimeDeltaVector(expected_compositor1,
+                       std::vector<int>{300, -1, -1, -1, -1, 300, 300});
+  base::TimeDelta expected_total1 =
+      base::Microseconds(2700) + kTouchEventTransition;
+  CompositorFrameReporter::EventLatencyInfo actual_predictions1 =
+      CompositorFrameReporter::EventLatencyInfo(kNumDispatchStages,
+                                                kNumOfStages);
+  pipeline_reporter_->CalculateEventLatencyPrediction(
+      actual_predictions1, kLatencyPredictionDeviationThreshold);
+
+  // Test with all previous stage predictions.
+  std::vector<base::TimeDelta> expected_dispatch2(kNumDispatchStages,
+                                                  base::Microseconds(-1));
+  IntToTimeDeltaVector(expected_dispatch2,
+                       std::vector<int>{262, 300, 412, 225, 450});
+  base::TimeDelta expected_transition2 = base::Microseconds(393);
+  std::vector<base::TimeDelta> expected_compositor2(kNumOfStages,
+                                                    base::Microseconds(-1));
+  IntToTimeDeltaVector(expected_compositor2,
+                       std::vector<int>{465, 500, 90, 720, 410, 742, 390});
+  base::TimeDelta expected_total2 = base::Microseconds(5359);
+  CompositorFrameReporter::EventLatencyInfo actual_predictions2 =
+      CompositorFrameReporter::EventLatencyInfo(kNumDispatchStages,
+                                                kNumOfStages);
+  IntToTimeDeltaVector(actual_predictions2.dispatch_durations,
+                       std::vector<int>{250, 300, 450, 200, 500});
+  actual_predictions2.transition_duration = base::Microseconds(420);
+  IntToTimeDeltaVector(actual_predictions2.compositor_durations,
+                       std::vector<int>{520, 500, 90, 720, 410, 890, 420});
+  pipeline_reporter_->CalculateEventLatencyPrediction(
+      actual_predictions2, kLatencyPredictionDeviationThreshold);
+
+  for (int i = 0; i < kNumDispatchStages; i++) {
+    EXPECT_EQ(expected_dispatch1[i], actual_predictions1.dispatch_durations[i]);
+    EXPECT_EQ(expected_dispatch2[i], actual_predictions2.dispatch_durations[i]);
+  }
+  for (int i = 0; i < kNumOfStages; i++) {
+    EXPECT_EQ(expected_compositor1[i],
+              actual_predictions1.compositor_durations[i]);
+    EXPECT_EQ(expected_compositor2[i],
+              actual_predictions2.compositor_durations[i]);
+  }
+  EXPECT_EQ(expected_transition1, actual_predictions1.transition_duration);
+  EXPECT_EQ(expected_total1, actual_predictions1.total_duration);
+  EXPECT_EQ(expected_transition2, actual_predictions2.transition_duration);
+  EXPECT_EQ(expected_total2, actual_predictions2.total_duration);
+
+  pipeline_reporter_ = nullptr;
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/chrome/VERSION b/chrome/VERSION
index a98f709..7746fec 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=106
 MINOR=0
-BUILD=5218
+BUILD=5219
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 547adf5f..6a788830 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1770,6 +1770,7 @@
     "//services/device/public/java:geolocation_java",
     "//services/device/public/java:geolocation_java_test_support",
     "//services/device/public/mojom:mojom_java",
+    "//services/media_session/public/mojom:mojom_java",
     "//services/network/public/mojom:mojom_java",
     "//services/network/public/mojom:mojom_proxy_config_java",
     "//services/network/public/mojom:url_loader_base_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
index 089803a..a56e368d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
@@ -18,7 +18,6 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.CollectionUtil;
-import org.chromium.base.Consumer;
 import org.chromium.base.PackageManagerUtils;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
@@ -65,13 +64,12 @@
      * @param canDrawOutsideScreen Whether floating action bar can be drawn outside the screen.
      */
     public ChromeActionModeHandler(ActivityTabProvider activityTabProvider,
-            Consumer<Boolean> actionBarObserver, Callback<String> searchCallback,
-            Supplier<ShareDelegate> shareDelegateSupplier, boolean canDrawOutsideScreen) {
+            Callback<String> searchCallback, Supplier<ShareDelegate> shareDelegateSupplier,
+            boolean canDrawOutsideScreen) {
         mInitWebContentsObserver = (webContents) -> {
             SelectionPopupController.fromWebContents(webContents)
-                    .setActionModeCallback(
-                            new ActionModeCallback(mActiveTab, webContents, actionBarObserver,
-                                    searchCallback, shareDelegateSupplier, canDrawOutsideScreen));
+                    .setActionModeCallback(new ActionModeCallback(mActiveTab, webContents,
+                            searchCallback, shareDelegateSupplier, canDrawOutsideScreen));
         };
 
         mActivityTabTabObserver =
@@ -105,7 +103,6 @@
 
         private final Tab mTab;
         private final ActionModeCallbackHelper mHelper;
-        private final Consumer<Boolean> mActionBarObserver;
         private final Callback<String> mSearchCallback;
         private final Supplier<ShareDelegate> mShareDelegateSupplier;
         private final boolean mCanDrawOutsideScreen;
@@ -113,12 +110,10 @@
         // Used for recording UMA histograms.
         private long mContextMenuStartTime;
 
-        ActionModeCallback(Tab tab, WebContents webContents, Consumer<Boolean> observer,
-                Callback<String> searchCallback, Supplier<ShareDelegate> shareDelegateSupplier,
-                boolean canDrawOutsideScreen) {
+        ActionModeCallback(Tab tab, WebContents webContents, Callback<String> searchCallback,
+                Supplier<ShareDelegate> shareDelegateSupplier, boolean canDrawOutsideScreen) {
             mTab = tab;
             mHelper = getActionModeCallbackHelper(webContents);
-            mActionBarObserver = observer;
             mSearchCallback = searchCallback;
             mShareDelegateSupplier = shareDelegateSupplier;
             mCanDrawOutsideScreen = canDrawOutsideScreen;
@@ -133,7 +128,6 @@
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
             mContextMenuStartTime = System.currentTimeMillis();
-            notifyContextualActionBarVisibilityChanged(true);
 
             int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT
                     | ActionModeCallbackHelper.MENU_ITEM_SHARE;
@@ -151,7 +145,6 @@
         @Override
         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
             recordUserAction();
-            notifyContextualActionBarVisibilityChanged(true);
             boolean res = mHelper.onPrepareActionMode(mode, menu);
             Set<String> browsers = getPackageNames(PackageManagerUtils.queryAllWebBrowsersInfo());
             Set<String> launchers = getPackageNames(PackageManagerUtils.queryAllLaunchersInfo());
@@ -233,7 +226,6 @@
         @Override
         public void onDestroyActionMode(ActionMode mode) {
             mHelper.onDestroyActionMode();
-            notifyContextualActionBarVisibilityChanged(false);
         }
 
         @Override
@@ -252,10 +244,6 @@
             }
         }
 
-        private void notifyContextualActionBarVisibilityChanged(boolean show) {
-            mActionBarObserver.accept(show);
-        }
-
         private Set<String> getPackageNames(List<ResolveInfo> list) {
             Set<String> set = new HashSet<>();
             CollectionUtil.forEach(list, (info) -> set.add(info.activityInfo.packageName));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureActivity.java
index d902a6f..188a7ee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureActivity.java
@@ -16,6 +16,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Icon;
 import android.os.Build;
@@ -106,20 +108,56 @@
 
     private MediaSessionBroadcastReceiver mMediaSessionReceiver;
 
-    private MediaActionButtonsManager mMediaActionsButtonsManager;
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    MediaActionButtonsManager mMediaActionsButtonsManager;
 
     /**
      * A helper class for managing media action buttons in PictureInPicture window.
      */
-    private class MediaActionButtonsManager {
-        private final RemoteAction mPreviousTrack;
-        private final RemoteAction mPlay;
-        private final RemoteAction mPause;
-        private final RemoteAction mReplay;
-        private final RemoteAction mNextTrack;
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    class MediaActionButtonsManager {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mPreviousTrack;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mPlay;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mPause;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mReplay;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mNextTrack;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final RemoteAction mHangUp;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final ToggleRemoteAction mMicrophone;
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        final ToggleRemoteAction mCamera;
 
         private @PlaybackState int mPlaybackState;
 
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        class ToggleRemoteAction {
+            private final RemoteAction mActionOn;
+            private final RemoteAction mActionOff;
+            private boolean mState;
+
+            private ToggleRemoteAction(
+                    RemoteAction actionOn, RemoteAction actionOff) {
+                mActionOn = actionOn;
+                mActionOff = actionOff;
+                mState = false;
+            }
+
+            private void setState(boolean on) {
+                mState = on;
+            }
+
+            @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+            RemoteAction getAction() {
+                return mState ? mActionOn : mActionOff;
+            }
+        }
+
         /** A set of {@link MediaSessionAction}. */
         private HashSet<Integer> mVisibleActions;
 
@@ -134,35 +172,85 @@
                     R.string.accessibility_replay);
             mNextTrack = createRemoteAction(MediaSessionAction.NEXT_TRACK,
                     R.drawable.ic_skip_next_white_36dp, R.string.accessibility_next_track);
+            mHangUp = createRemoteAction(MediaSessionAction.HANG_UP,
+                    R.drawable.ic_call_end_white_36dp, R.string.accessibility_hang_up);
+            mMicrophone = new ToggleRemoteAction(
+                    createRemoteAction(MediaSessionAction.TOGGLE_MICROPHONE,
+                            R.drawable.ic_mic_white_36dp, R.string.accessibility_mute_microphone),
+                    createRemoteAction(MediaSessionAction.TOGGLE_MICROPHONE,
+                            R.drawable.ic_mic_off_white_36dp,
+                            R.string.accessibility_unmute_microphone));
+            mCamera = new ToggleRemoteAction(createRemoteAction(MediaSessionAction.TOGGLE_CAMERA,
+                                                     R.drawable.ic_videocam_white_36dp,
+                                                     R.string.accessibility_turn_off_camera),
+                    createRemoteAction(MediaSessionAction.TOGGLE_CAMERA,
+                            R.drawable.ic_videocam_off_white_36dp,
+                            R.string.accessibility_turn_on_camera));
 
             mPlaybackState = PlaybackState.END_OF_VIDEO;
             mVisibleActions = new HashSet<>();
         }
 
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
         @SuppressLint("NewApi")
-        private ArrayList<RemoteAction> getActionsForPictureInPictureParams() {
+        ArrayList<RemoteAction> getActionsForPictureInPictureParams() {
             ArrayList<RemoteAction> actions = new ArrayList<>();
 
-            mPreviousTrack.setEnabled(mVisibleActions.contains(MediaSessionAction.PREVIOUS_TRACK));
-            actions.add(mPreviousTrack);
-
-            RemoteAction playPauseAction = null;
-            switch (mPlaybackState) {
-                case PlaybackState.PLAYING:
-                    playPauseAction = mPause;
-                    break;
-                case PlaybackState.PAUSED:
-                    playPauseAction = mPlay;
-                    break;
-                case PlaybackState.END_OF_VIDEO:
-                    playPauseAction = mReplay;
-                    break;
+            boolean shouldShowPreviousNextTrack =
+                    mVisibleActions.contains(MediaSessionAction.PREVIOUS_TRACK)
+                    || mVisibleActions.contains(MediaSessionAction.NEXT_TRACK);
+            if (shouldShowPreviousNextTrack) {
+                mPreviousTrack.setEnabled(
+                        mVisibleActions.contains(MediaSessionAction.PREVIOUS_TRACK));
+                actions.add(mPreviousTrack);
             }
-            playPauseAction.setEnabled(mVisibleActions.contains(MediaSessionAction.PLAY));
-            actions.add(playPauseAction);
 
-            mNextTrack.setEnabled(mVisibleActions.contains(MediaSessionAction.NEXT_TRACK));
-            actions.add(mNextTrack);
+            if (mVisibleActions.contains(MediaSessionAction.PLAY)) {
+                switch (mPlaybackState) {
+                    case PlaybackState.PLAYING:
+                        actions.add(mPause);
+                        break;
+                    case PlaybackState.PAUSED:
+                        actions.add(mPlay);
+                        break;
+                    case PlaybackState.END_OF_VIDEO:
+                        actions.add(mReplay);
+                        break;
+                }
+            }
+
+            if (shouldShowPreviousNextTrack) {
+                mNextTrack.setEnabled(mVisibleActions.contains(MediaSessionAction.NEXT_TRACK));
+                actions.add(mNextTrack);
+            }
+
+            if (mVisibleActions.contains(MediaSessionAction.TOGGLE_MICROPHONE)) {
+                actions.add(mMicrophone.getAction());
+            }
+
+            if (mVisibleActions.contains(MediaSessionAction.TOGGLE_CAMERA)) {
+                actions.add(mCamera.getAction());
+            }
+
+            if (mVisibleActions.contains(MediaSessionAction.HANG_UP)) {
+                actions.add(mHangUp);
+            }
+
+            // Insert a disabled dummy remote action with transparent icon if action list is empty.
+            // This is a workaround of the issue that android picture-in-picture will fallback to
+            // default MediaSession when action list given is empty.
+            // TODO (jazzhsu): Remove this when android picture-in-picture can accept empty list and
+            // not fallback to default MediaSession.
+            if (actions.isEmpty()) {
+                RemoteAction dummyAction = new RemoteAction(
+                        Icon.createWithBitmap(Bitmap.createBitmap(
+                                new int[] {Color.TRANSPARENT}, 1, 1, Bitmap.Config.ARGB_8888)),
+                        "", "",
+                        PendingIntent.getBroadcast(getApplicationContext(), -1,
+                                new Intent(MEDIA_ACTION), PendingIntent.FLAG_IMMUTABLE));
+                dummyAction.setEnabled(false);
+                actions.add(dummyAction);
+            }
 
             return actions;
         }
@@ -180,8 +268,16 @@
             mPlaybackState = playbackState;
         }
 
+        private void setMicrophoneMuted(boolean muted) {
+            mMicrophone.setState(!muted);
+        }
+
+        private void setCameraOn(boolean cameraOn) {
+            mCamera.setState(cameraOn);
+        }
+
         /**
-         * Create a disabled remote action for picture-in-picture window.
+         * Create a remote action for picture-in-picture window.
          *
          * @param action {@link MediaSessionAction} that the action button is corresponding to.
          * @param iconResourceId used for getting icon associated with the id.
@@ -198,13 +294,10 @@
                     PendingIntent.getBroadcast(getApplicationContext(), action, intent,
                             PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
 
-            RemoteAction remoteAction = new RemoteAction(
+            return new RemoteAction(
                     Icon.createWithResource(getApplicationContext(), iconResourceId),
                     getApplicationContext().getResources().getText(titleResourceId), "",
                     pendingIntent);
-
-            remoteAction.setEnabled(false);
-            return remoteAction;
         }
     }
 
@@ -235,6 +328,15 @@
                 case MediaSessionAction.NEXT_TRACK:
                     PictureInPictureActivityJni.get().nextTrack(nativeOverlayWindowAndroid);
                     return;
+                case MediaSessionAction.TOGGLE_MICROPHONE:
+                    PictureInPictureActivityJni.get().toggleMicrophone(nativeOverlayWindowAndroid);
+                    return;
+                case MediaSessionAction.TOGGLE_CAMERA:
+                    PictureInPictureActivityJni.get().toggleCamera(nativeOverlayWindowAndroid);
+                    return;
+                case MediaSessionAction.HANG_UP:
+                    PictureInPictureActivityJni.get().hangUp(nativeOverlayWindowAndroid);
+                    return;
                 default:
                     return;
             }
@@ -484,14 +586,28 @@
         mAspectRatio = new Rational(width, height);
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     @CalledByNative
-    private void setPlaybackState(@PlaybackState int playbackState) {
+    void setPlaybackState(@PlaybackState int playbackState) {
         mMediaActionsButtonsManager.updatePlaybackState(playbackState);
         updatePictureInPictureParams();
     }
 
     @CalledByNative
-    private void updateVisibleActions(int[] actions) {
+    private void setMicrophoneMuted(boolean muted) {
+        mMediaActionsButtonsManager.setMicrophoneMuted(muted);
+        updatePictureInPictureParams();
+    }
+
+    @CalledByNative
+    private void setCameraState(boolean turnedOn) {
+        mMediaActionsButtonsManager.setCameraOn(turnedOn);
+        updatePictureInPictureParams();
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    @CalledByNative
+    void updateVisibleActions(int[] actions) {
         HashSet<Integer> visibleActions = new HashSet<>();
         for (int action : actions) visibleActions.add(action);
         mMediaActionsButtonsManager.updateVisibleActions(visibleActions);
@@ -604,6 +720,9 @@
         void togglePlayPause(long nativeOverlayWindowAndroid);
         void nextTrack(long nativeOverlayWindowAndroid);
         void previousTrack(long nativeOverlayWindowAndroid);
+        void toggleMicrophone(long nativeOverlayWindowAndroid);
+        void toggleCamera(long nativeOverlayWindowAndroid);
+        void hangUp(long nativeOverlayWindowAndroid);
 
         void compositorViewCreated(long nativeOverlayWindowAndroid, CompositorView compositorView);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index 04341cf..641f82f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -23,7 +23,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.ActionBar;
 import androidx.appcompat.app.AppCompatActivity;
 
 import com.google.android.material.appbar.AppBarLayout;
@@ -1246,23 +1245,6 @@
     }
 
     /**
-     * Called when the contextual action bar's visibility has changed (i.e. the widget shown
-     * when you can copy/paste text after long press).
-     * @param visible Whether the contextual action bar is now visible.
-     */
-    public void onActionBarVisibilityChanged(boolean visible) {
-        ActionBar actionBar = mActionBarDelegate.getSupportActionBar();
-        if (!visible && actionBar != null) actionBar.hide();
-        if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) {
-            if (visible) {
-                mActionModeController.startShowAnimation();
-            } else {
-                mActionModeController.startHideAnimation();
-            }
-        }
-    }
-
-    /**
      * @return  Whether the UrlBar currently has focus.
      */
     public boolean isUrlBarFocused() {
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 894e919..6f979f3 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
@@ -83,6 +83,7 @@
 import org.chromium.chrome.browser.messages.ChromeMessageAutodismissDurationProvider;
 import org.chromium.chrome.browser.messages.ChromeMessageQueueMediator;
 import org.chromium.chrome.browser.messages.MessageContainerCoordinator;
+import org.chromium.chrome.browser.messages.MessageContainerObserver;
 import org.chromium.chrome.browser.messages.MessagesResourceMapperInitializer;
 import org.chromium.chrome.browser.omnibox.OmniboxFocusReason;
 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader;
@@ -259,6 +260,7 @@
     protected ManagedMessageDispatcher mMessageDispatcher;
     @Nullable
     private MessageContainerCoordinator mMessageContainerCoordinator;
+    private MessageContainerObserver mMessageContainerObserver;
     @Nullable
     private ChromeMessageQueueMediator mMessageQueueMediator;
     private LayoutManagerImpl mLayoutManager;
@@ -525,6 +527,9 @@
         }
 
         if (mMessageContainerCoordinator != null) {
+            if (mMessageContainerObserver != null) {
+                mMessageContainerCoordinator.removeObserver(mMessageContainerObserver);
+            }
             mMessageContainerCoordinator.destroy();
             mMessageContainerCoordinator = null;
         }
@@ -673,8 +678,8 @@
             };
             mModalDialogManagerSupplier.get().addObserver(mModalDialogManagerObserver);
         }
-        mChromeActionModeHandler = new ChromeActionModeHandler(mActivityTabProvider,
-                mToolbarManager::onActionBarVisibilityChanged, (searchText) -> {
+        mChromeActionModeHandler =
+                new ChromeActionModeHandler(mActivityTabProvider, (searchText) -> {
                     if (mTabModelSelectorSupplier.get() == null) return;
 
                     String query = ActionModeCallbackHelper.sanitizeQuery(
@@ -737,6 +742,18 @@
             MessageContainer container = mActivity.findViewById(R.id.message_container);
             mMessageContainerCoordinator =
                     new MessageContainerCoordinator(container, mBrowserControlsManager);
+            mMessageContainerObserver = new MessageContainerObserver() {
+                @Override
+                public void onShowMessageContainer() {
+                    if (mPageZoomCoordinator != null) {
+                        mPageZoomCoordinator.hide();
+                    }
+                }
+
+                @Override
+                public void onHideMessageContainer() {}
+            };
+            mMessageContainerCoordinator.addObserver(mMessageContainerObserver);
             mMessageDispatcher = MessagesFactory.createMessageDispatcher(container,
                     mMessageContainerCoordinator::getMessageMaxTranslation,
                     new ChromeMessageAutodismissDurationProvider(),
@@ -1137,6 +1154,13 @@
                 mMicStateObserver = voiceToolbarButtonController::updateMicButtonState;
                 voiceRecognitionHandler.addObserver(mMicStateObserver);
             }
+
+            mSnackbarManagerSupplier.get().isShowingSupplier().addObserver((Boolean isShowing) -> {
+                if (isShowing && mPageZoomCoordinator != null) {
+                    // On show snackbar, hide page zoom dialog
+                    mPageZoomCoordinator.hide();
+                }
+            });
         }
     }
 
@@ -1242,6 +1266,7 @@
                 @Override
                 public void onMenuVisibilityChanged(boolean isVisible) {
                     if (isVisible && mPageZoomCoordinator != null) {
+                        // On show app menu, hide page zoom dialog
                         mPageZoomCoordinator.hide();
                     }
                 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java
index e8a8cef..bd6a6cd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java
@@ -26,9 +26,9 @@
     interface Natives {
         void onWebApkInfoRetrieved(long nativeWebApkHandlerDelegate, String name, String shortName,
                 String packageName, String id, int shellApkVersion, int versionCode, String uri,
-                String scope, String manifestUrl, String manifestStartUrl, int displayMode,
-                int orientation, long themeColor, long backgroundColor, long lastUpdateCheckTimeMs,
-                long lastUpdateCompletionTimeMs, boolean relaxUpdates,
+                String scope, String manifestUrl, String manifestStartUrl, String manifestId,
+                int displayMode, int orientation, long themeColor, long backgroundColor,
+                long lastUpdateCheckTimeMs, long lastUpdateCompletionTimeMs, boolean relaxUpdates,
                 String backingBrowserPackageName, boolean isBackingBrowser, String updateStatus);
     }
 
@@ -106,9 +106,9 @@
                 webApkInfo.shortName(), webApkInfo.webApkPackageName(), webApkInfo.id(),
                 webApkInfo.shellApkVersion(), packageInfo.versionCode, webApkInfo.url(),
                 webApkInfo.scopeUrl(), webApkInfo.manifestUrl(), webApkInfo.manifestStartUrl(),
-                webApkInfo.displayMode(), webApkInfo.orientation(), webApkInfo.toolbarColor(),
-                webApkInfo.backgroundColor(), lastUpdateCheckTimeMsForStorage,
-                lastUpdateCompletionTimeMsInStorage, relaxUpdatesForStorage,
-                backingBrowserPackageName, isBackingBrowser, updateStatus);
+                webApkInfo.manifestId(), webApkInfo.displayMode(), webApkInfo.orientation(),
+                webApkInfo.toolbarColor(), webApkInfo.backgroundColor(),
+                lastUpdateCheckTimeMsForStorage, lastUpdateCompletionTimeMsInStorage,
+                relaxUpdatesForStorage, backingBrowserPackageName, isBackingBrowser, updateStatus);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/PictureInPictureActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/PictureInPictureActivityTest.java
index 634d3ed..0857e46 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/PictureInPictureActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/PictureInPictureActivityTest.java
@@ -13,6 +13,7 @@
 import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
 
 import android.app.Activity;
+import android.app.RemoteAction;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -48,9 +49,12 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ActivityTestUtils;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.browser.overlay_window.PlaybackState;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.content_public.browser.test.util.WebContentsUtils;
+import org.chromium.media_session.mojom.MediaSessionAction;
 
+import java.util.ArrayList;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
@@ -183,6 +187,69 @@
         verify(mNativeMock, times(0)).onViewSizeChanged(anyInt(), anyInt(), anyInt());
     }
 
+    @Test
+    @MediumTest
+    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
+    public void testMediaActions() throws Throwable {
+        PictureInPictureActivity activity = startPictureInPictureActivity();
+        PictureInPictureActivity.MediaActionButtonsManager manager =
+                activity.mMediaActionsButtonsManager;
+
+        activity.updateVisibleActions(new int[] {MediaSessionAction.PLAY});
+        activity.setPlaybackState(PlaybackState.PAUSED);
+        ArrayList<RemoteAction> actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 1);
+        Assert.assertEquals(actions.get(0), manager.mPlay);
+
+        activity.setPlaybackState(PlaybackState.PLAYING);
+        actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.get(0), manager.mPause);
+
+        // Both next track and previous track button should be visible when only one of them is
+        // enabled. The one that is not handled should be visible and disabled.
+        activity.updateVisibleActions(
+                new int[] {MediaSessionAction.PLAY, MediaSessionAction.PREVIOUS_TRACK});
+        actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 3);
+        Assert.assertEquals(actions.get(0), manager.mPreviousTrack);
+        Assert.assertEquals(actions.get(2), manager.mNextTrack);
+        Assert.assertTrue(actions.get(0).isEnabled());
+        Assert.assertFalse(actions.get(2).isEnabled());
+
+        // When all actions are not handled, there should be a dummy action presented to prevent
+        // android picture-in-picture from using default MediaSession.
+        activity.updateVisibleActions(new int[] {});
+        actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 1);
+        Assert.assertFalse(actions.get(0).isEnabled());
+        testExitOn(activity, () -> activity.close());
+    }
+
+    @Test
+    @MediumTest
+    @MinAndroidSdkLevel(Build.VERSION_CODES.O)
+    public void testMediaActionsForVideoConferencing() throws Throwable {
+        PictureInPictureActivity activity = startPictureInPictureActivity();
+        PictureInPictureActivity.MediaActionButtonsManager manager =
+                activity.mMediaActionsButtonsManager;
+
+        activity.updateVisibleActions(new int[] {MediaSessionAction.TOGGLE_MICROPHONE});
+        ArrayList<RemoteAction> actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 1);
+        Assert.assertEquals(actions.get(0), manager.mMicrophone.getAction());
+
+        activity.updateVisibleActions(new int[] {MediaSessionAction.TOGGLE_CAMERA});
+        actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 1);
+        Assert.assertEquals(actions.get(0), manager.mCamera.getAction());
+
+        activity.updateVisibleActions(new int[] {MediaSessionAction.HANG_UP});
+        actions = manager.getActionsForPictureInPictureParams();
+        Assert.assertEquals(actions.size(), 1);
+        Assert.assertEquals(actions.get(0), manager.mHangUp);
+        testExitOn(activity, () -> activity.close());
+    }
+
     private WebContents getWebContents() {
         return mActivityTestRule.getActivity().getCurrentWebContents();
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java
index 016d201..d093e50 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java
@@ -60,7 +60,7 @@
 
     private class TestChromeActionModeCallback extends ChromeActionModeHandler.ActionModeCallback {
         TestChromeActionModeCallback(Tab tab, ActionModeCallbackHelper helper) {
-            super(tab, null, visible -> {}, urlParams -> {}, null, false);
+            super(tab, null, urlParams -> {}, null, false);
         }
 
         @Override
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 5178ba1..0f6faa78 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2237,9 +2237,6 @@
   <message name="IDS_SETTINGS_SEARCH_ENGINES_NO_INACTIVE_SHORTCUTS" desc="Text shown when the 'Inactive Shortcuts' section is empty">
     No inactive shortcuts
   </message>
-  <message name="IDS_SETTINGS_SEARCH_ENGINES_OTHER_ENGINES" desc="Label for 'other' Search Engines section">
-    Other search engines
-  </message>
   <message name="IDS_SETTINGS_SEARCH_ENGINES_NO_OTHER_ENGINES" desc="Label shown when the 'other' Search engines section is empty">
     Other saved search engines will appear here
   </message>
@@ -2258,9 +2255,6 @@
   <message name="IDS_SETTINGS_SEARCH_ENGINES_INACTIVE_SITE" desc="Label for a table column that holds the name of a site or page in the 'Inactive shortcuts' section">
     Inactive sites
   </message>
-  <message name="IDS_SETTINGS_SEARCH_ENGINES_KEYWORD" desc="Label for Keyword column header for a search engine">
-    Keyword
-  </message>
   <message name="IDS_SETTINGS_SEARCH_ENGINES_SHORTCUT" desc="Label for Shortcut column header for a search engine or site search entry">
     Shortcut
   </message>
diff --git a/chrome/browser/android/webapk/webapk_handler_delegate.cc b/chrome/browser/android/webapk/webapk_handler_delegate.cc
index eefbce9..a261762b 100644
--- a/chrome/browser/android/webapk/webapk_handler_delegate.cc
+++ b/chrome/browser/android/webapk/webapk_handler_delegate.cc
@@ -44,6 +44,7 @@
     const JavaParamRef<jstring>& jscope,
     const JavaParamRef<jstring>& jmanifest_url,
     const JavaParamRef<jstring>& jmanifest_start_url,
+    const JavaParamRef<jstring>& jmanifest_id,
     const jint jdisplay_mode,
     const jint jorientation,
     const jlong jtheme_color,
@@ -60,6 +61,11 @@
         env, jbacking_browser_package_name);
   }
 
+  std::string manifest_id;
+  if (jmanifest_id) {
+    manifest_id = base::android::ConvertJavaStringToUTF8(env, jmanifest_id);
+  }
+
   callback_.Run(WebApkInfo(
       base::android::ConvertJavaStringToUTF8(env, jname),
       base::android::ConvertJavaStringToUTF8(env, jshort_name),
@@ -70,7 +76,7 @@
       base::android::ConvertJavaStringToUTF8(env, jscope),
       base::android::ConvertJavaStringToUTF8(env, jmanifest_url),
       base::android::ConvertJavaStringToUTF8(env, jmanifest_start_url),
-      static_cast<blink::mojom::DisplayMode>(jdisplay_mode),
+      manifest_id, static_cast<blink::mojom::DisplayMode>(jdisplay_mode),
       static_cast<device::mojom::ScreenOrientationLockType>(jorientation),
       ui::JavaColorToOptionalSkColor(jtheme_color),
       ui::JavaColorToOptionalSkColor(jbackground_color),
diff --git a/chrome/browser/android/webapk/webapk_handler_delegate.h b/chrome/browser/android/webapk/webapk_handler_delegate.h
index 81d3756..1a63b5c 100644
--- a/chrome/browser/android/webapk/webapk_handler_delegate.h
+++ b/chrome/browser/android/webapk/webapk_handler_delegate.h
@@ -39,6 +39,7 @@
       const base::android::JavaParamRef<jstring>& jscope,
       const base::android::JavaParamRef<jstring>& jmanifest_url,
       const base::android::JavaParamRef<jstring>& jmanifest_start_url,
+      const base::android::JavaParamRef<jstring>& jmanifest_id,
       const jint jdisplay_mode,
       const jint jorientation,
       const jlong jtheme_color,
diff --git a/chrome/browser/android/webapk/webapk_info.cc b/chrome/browser/android/webapk/webapk_info.cc
index b5680f6..cffb0e1 100644
--- a/chrome/browser/android/webapk/webapk_info.cc
+++ b/chrome/browser/android/webapk/webapk_info.cc
@@ -16,6 +16,7 @@
                        std::string scope,
                        std::string manifest_url,
                        std::string manifest_start_url,
+                       std::string manifest_id,
                        blink::mojom::DisplayMode display,
                        device::mojom::ScreenOrientationLockType orientation,
                        absl::optional<SkColor> theme_color,
@@ -36,6 +37,7 @@
       scope(std::move(scope)),
       manifest_url(std::move(manifest_url)),
       manifest_start_url(std::move(manifest_start_url)),
+      manifest_id(std::move(manifest_id)),
       display(display),
       orientation(orientation),
       theme_color(theme_color),
diff --git a/chrome/browser/android/webapk/webapk_info.h b/chrome/browser/android/webapk/webapk_info.h
index 653a9f84..1ace73a 100644
--- a/chrome/browser/android/webapk/webapk_info.h
+++ b/chrome/browser/android/webapk/webapk_info.h
@@ -30,6 +30,7 @@
              std::string scope,
              std::string manifest_url,
              std::string manifest_start_url,
+             std::string manifest_id,
              blink::mojom::DisplayMode display,
              device::mojom::ScreenOrientationLockType orientation,
              absl::optional<SkColor> theme_color,
@@ -71,6 +72,7 @@
   std::string scope;
   std::string manifest_url;
   std::string manifest_start_url;
+  std::string manifest_id;
   blink::mojom::DisplayMode display;
   device::mojom::ScreenOrientationLockType orientation;
   absl::optional<SkColor> theme_color;
diff --git a/chrome/browser/ash/arc/policy/arc_android_management_checker.cc b/chrome/browser/ash/arc/policy/arc_android_management_checker.cc
index 09e3c7a..05471eb 100644
--- a/chrome/browser/ash/arc/policy/arc_android_management_checker.cc
+++ b/chrome/browser/ash/arc/policy/arc_android_management_checker.cc
@@ -72,12 +72,12 @@
 void ArcAndroidManagementChecker::StartCheck(CheckCallback callback) {
   DCHECK(callback_.is_null());
 
-  // Do not send requests for Chrome OS managed users, nor for well-known
-  // consumer domains.
+  // No need to check Android Management if the user is a Chrome OS managed
+  // user, or belongs to a well-known non-enterprise domain.
   if (policy_util::IsAccountManaged(profile_) ||
       policy::BrowserPolicyConnector::IsNonEnterpriseUser(
           profile_->GetProfileUserName())) {
-    std::move(callback).Run(policy::AndroidManagementClient::Result::UNMANAGED);
+    std::move(callback).Run(CheckResult::ALLOWED);
     return;
   }
 
@@ -115,7 +115,7 @@
 
   if (!identity_manager_->HasAccountWithRefreshToken(device_account_id_)) {
     VLOG(2) << "No refresh token is available for android management check.";
-    std::move(callback_).Run(policy::AndroidManagementClient::Result::ERROR);
+    std::move(callback_).Run(CheckResult::ERROR);
     return;
   }
 
@@ -126,16 +126,28 @@
 }
 
 void ArcAndroidManagementChecker::OnAndroidManagementChecked(
-    policy::AndroidManagementClient::Result result) {
+    policy::AndroidManagementClient::Result management_result) {
   DCHECK(!callback_.is_null());
-  VLOG(2) << "Android management check done " << result << ".";
+  VLOG(2) << "Android management check done " << management_result << ".";
   if (retry_on_error_ &&
-      result == policy::AndroidManagementClient::Result::ERROR) {
+      management_result == policy::AndroidManagementClient::Result::ERROR) {
     ScheduleRetry();
     return;
   }
 
-  std::move(callback_).Run(result);
+  CheckResult check_result = CheckResult::ERROR;
+  switch (management_result) {
+    case policy::AndroidManagementClient::Result::MANAGED:
+      check_result = CheckResult::DISALLOWED;
+      break;
+    case policy::AndroidManagementClient::Result::UNMANAGED:
+      check_result = CheckResult::ALLOWED;
+      break;
+    case policy::AndroidManagementClient::Result::ERROR:
+      check_result = CheckResult::ERROR;
+      break;
+  }
+  std::move(callback_).Run(check_result);
 }
 
 void ArcAndroidManagementChecker::ScheduleRetry() {
diff --git a/chrome/browser/ash/arc/policy/arc_android_management_checker.h b/chrome/browser/ash/arc/policy/arc_android_management_checker.h
index fe4653d..eea136d 100644
--- a/chrome/browser/ash/arc/policy/arc_android_management_checker.h
+++ b/chrome/browser/ash/arc/policy/arc_android_management_checker.h
@@ -15,8 +15,17 @@
 
 namespace arc {
 
+// ArcAndroidManagementChecker checks if Android management is enabled for the
+// user while not being a managed ChromeOS user. ARC is disabled if these
+// conditions are met (b/26848810).
 class ArcAndroidManagementChecker : public signin::IdentityManager::Observer {
  public:
+  enum class CheckResult {
+    ALLOWED,     // It's OK to enable ARC for the user.
+    DISALLOWED,  // The user shouldn't use ARC.
+    ERROR,       // There was an error.
+  };
+
   ArcAndroidManagementChecker(Profile* profile, bool retry_on_error);
 
   ArcAndroidManagementChecker(const ArcAndroidManagementChecker&) = delete;
@@ -31,14 +40,13 @@
   // |result|. This must not be called if there is inflight check.
   // If the instance is destructed while it has inflight check, then the
   // check will be cancelled and |callback| will not be called.
-  using CheckCallback =
-      base::OnceCallback<void(policy::AndroidManagementClient::Result result)>;
+  using CheckCallback = base::OnceCallback<void(CheckResult result)>;
   void StartCheck(CheckCallback callback);
 
  private:
   void StartCheckInternal();
   void OnAndroidManagementChecked(
-      policy::AndroidManagementClient::Result result);
+      policy::AndroidManagementClient::Result management_result);
   void ScheduleRetry();
 
   // Ensures the refresh token is loaded in the |identity_manager|.
diff --git a/chrome/browser/ash/arc/session/arc_session_manager.cc b/chrome/browser/ash/arc/session/arc_session_manager.cc
index d2c5724d..684d3f0 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager.cc
@@ -42,7 +42,6 @@
 #include "chrome/browser/ash/arc/auth/arc_auth_service.h"
 #include "chrome/browser/ash/arc/optin/arc_terms_of_service_default_negotiator.h"
 #include "chrome/browser/ash/arc/optin/arc_terms_of_service_oobe_negotiator.h"
-#include "chrome/browser/ash/arc/policy/arc_android_management_checker.h"
 #include "chrome/browser/ash/arc/policy/arc_policy_util.h"
 #include "chrome/browser/ash/arc/session/arc_provisioning_result.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_service.h"
@@ -933,7 +932,7 @@
 }
 
 void ArcSessionManager::OnBackgroundAndroidManagementCheckedForTesting(
-    policy::AndroidManagementClient::Result result) {
+    ArcAndroidManagementChecker::CheckResult result) {
   OnBackgroundAndroidManagementChecked(result);
 }
 
@@ -1062,8 +1061,8 @@
     // Note: StartBackgroundAndroidManagementCheck() may call
     // OnBackgroundAndroidManagementChecked() synchronously (or
     // asynchronously). In the callback, Google Play Store enabled preference
-    // can be set to false if managed, and it triggers RequestDisable() via
-    // ArcPlayStoreEnabledPreferenceHandler.
+    // can be set to false if Android management is enabled, and it triggers
+    // RequestDisable() via ArcPlayStoreEnabledPreferenceHandler.
     // Thus, StartArc() should be called so that disabling should work even
     // if synchronous call case.
     StartBackgroundAndroidManagementCheck();
@@ -1285,18 +1284,18 @@
 }
 
 void ArcSessionManager::OnAndroidManagementChecked(
-    policy::AndroidManagementClient::Result result) {
+    ArcAndroidManagementChecker::CheckResult result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK_EQ(state_, State::CHECKING_ANDROID_MANAGEMENT);
   DCHECK(android_management_checker_);
   android_management_checker_.reset();
 
   switch (result) {
-    case policy::AndroidManagementClient::Result::UNMANAGED:
+    case ArcAndroidManagementChecker::CheckResult::ALLOWED:
       VLOG(1) << "Starting ARC for first sign in.";
       StartArc();
       break;
-    case policy::AndroidManagementClient::Result::MANAGED:
+    case ArcAndroidManagementChecker::CheckResult::DISALLOWED:
       ShowArcSupportHostError(
           ArcSupportHost::ErrorInfo(
               ArcSupportHost::Error::ANDROID_MANAGEMENT_REQUIRED_ERROR),
@@ -1304,7 +1303,7 @@
           false /* should_show_run_network_tests */);
       UpdateOptInCancelUMA(OptInCancelReason::ANDROID_MANAGEMENT_REQUIRED);
       break;
-    case policy::AndroidManagementClient::Result::ERROR:
+    case ArcAndroidManagementChecker::CheckResult::ERROR:
       ShowArcSupportHostError(
           ArcSupportHost::ErrorInfo(
               ArcSupportHost::Error::SERVER_COMMUNICATION_ERROR),
@@ -1321,8 +1320,8 @@
   DCHECK(!android_management_checker_);
 
   // Skip Android management check for testing.
-  // We also skip if Android management check for Kiosk and Public Session mode,
-  // because there are no managed human users for them exist.
+  // We also skip Android management check for Kiosk and Public Session mode,
+  // because they don't use real google accounts.
   if (IsArcOptInVerificationDisabled() || IsRobotOrOfflineDemoAccountMode() ||
       (!g_ui_enabled &&
        !g_enable_check_android_management_in_tests.value_or(false))) {
@@ -1337,7 +1336,7 @@
 }
 
 void ArcSessionManager::OnBackgroundAndroidManagementChecked(
-    policy::AndroidManagementClient::Result result) {
+    ArcAndroidManagementChecker::CheckResult result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (g_enable_check_android_management_in_tests.value_or(true)) {
@@ -1346,10 +1345,10 @@
   }
 
   switch (result) {
-    case policy::AndroidManagementClient::Result::UNMANAGED:
+    case ArcAndroidManagementChecker::CheckResult::ALLOWED:
       // Do nothing. ARC should be started already.
       break;
-    case policy::AndroidManagementClient::Result::MANAGED:
+    case ArcAndroidManagementChecker::CheckResult::DISALLOWED:
       if (base::FeatureList::IsEnabled(
               arc::kEnableUnmanagedToManagedTransitionFeature)) {
         WaitForPoliciesLoad();
@@ -1357,7 +1356,7 @@
         SetArcPlayStoreEnabledForProfile(profile_, false /* enabled */);
       }
       break;
-    case policy::AndroidManagementClient::Result::ERROR:
+    case ArcAndroidManagementChecker::CheckResult::ERROR:
       // This code should not be reached. For background check,
       // retry_on_error should be set.
       NOTREACHED();
diff --git a/chrome/browser/ash/arc/session/arc_session_manager.h b/chrome/browser/ash/arc/session/arc_session_manager.h
index fea2167..b25459b1 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager.h
+++ b/chrome/browser/ash/arc/session/arc_session_manager.h
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ash/arc/arc_support_host.h"
+#include "chrome/browser/ash/arc/policy/arc_android_management_checker.h"
 #include "chrome/browser/ash/arc/session/adb_sideloading_availability_delegate_impl.h"
 #include "chrome/browser/ash/arc/session/arc_app_id_provider_impl.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager_observer.h"
@@ -41,7 +42,6 @@
 constexpr const char kGeneratedCombinedPropertyFilePathVm[] =
     "/run/arcvm/host_generated/combined.prop";
 
-class ArcAndroidManagementChecker;
 class ArcDataRemover;
 class ArcDlcInstaller;
 class ArcFastAppReinstallStarter;
@@ -309,7 +309,7 @@
 
   // Invokes OnBackgroundAndroidManagementChecked as if the check is done.
   void OnBackgroundAndroidManagementCheckedForTesting(
-      policy::AndroidManagementClient::Result result);
+      ArcAndroidManagementChecker::CheckResult result);
 
   void reset_property_files_expansion_result() {
     property_files_expansion_result_.reset();
@@ -364,7 +364,7 @@
   // Called when the Android management check is done in opt-in flow or
   // OOBE flow.
   void OnAndroidManagementChecked(
-      policy::AndroidManagementClient::Result result);
+      ArcAndroidManagementChecker::CheckResult result);
 
   // Starts Android management check in background (in parallel with starting
   // ARC). This is for secondary or later ARC enabling.
@@ -378,7 +378,7 @@
   // Called when the background Android management check is done. It is
   // triggered when the second or later ARC boot timing.
   void OnBackgroundAndroidManagementChecked(
-      policy::AndroidManagementClient::Result result);
+      ArcAndroidManagementChecker::CheckResult result);
 
   // Requests to start ARC instance. Also, updates the internal state to
   // ACTIVE.
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
index 286d3ee..8b921e6b 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
@@ -2019,7 +2019,7 @@
 
   // Android management check response.
   arc_session_manager()->OnBackgroundAndroidManagementCheckedForTesting(
-      policy::AndroidManagementClient::Result::MANAGED);
+      ArcAndroidManagementChecker::CheckResult::DISALLOWED);
   base::RunLoop().RunUntilIdle();
 
   // Verify ARC state and ARC transition value.
diff --git a/chrome/browser/ash/customization/customization_document.cc b/chrome/browser/ash/customization/customization_document.cc
index bbc9c44..c2aaf2a 100644
--- a/chrome/browser/ash/customization/customization_document.cc
+++ b/chrome/browser/ash/customization/customization_document.cc
@@ -662,8 +662,8 @@
        it != external_loaders_.end(); ++it) {
     if (*it) {
       UpdateCachedManifest((*it)->profile());
-      (*it)->SetCurrentApps(
-          std::unique_ptr<base::DictionaryValue>(prefs->DeepCopy()));
+      (*it)->SetCurrentApps(base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(prefs->Clone())));
       SetOemFolderName((*it)->profile(), *root_);
     }
   }
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc
index 92dbac8..a537be2 100644
--- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc
+++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider.cc
@@ -127,7 +127,8 @@
           [](base::WeakPtr<MissiveClient> missive_client,
              ::reporting::SignedEncryptionInfo signed_encryption_info) {
             if (missive_client) {
-              missive_client->UpdateEncryptionKey(signed_encryption_info);
+              missive_client->UpdateEncryptionKey(
+                  std::move(signed_encryption_info));
             }
           },
           missive_client->GetWeakPtr()));
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc
index d008eb19..c67a4555 100644
--- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc
+++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc
@@ -77,11 +77,8 @@
             report_successful_upload_cb,
             encrypted_key_cb,
             /*upload_client_builder_cb=*/
-            base::BindRepeating([](::reporting::UploadClient::CreatedCallback
-                                       update_upload_client_cb) {
-              ::reporting::FakeUploadClient::Create(
-                  std::move(update_upload_client_cb));
-            }))) {}
+            base::BindRepeating(&::reporting::FakeUploadClient::Create))) {}
+
   TestEncryptedReportingServiceProvider(
       const TestEncryptedReportingServiceProvider& other) = delete;
   TestEncryptedReportingServiceProvider& operator=(
diff --git a/chrome/browser/ash/drive/drive_integration_service_browsertest.cc b/chrome/browser/ash/drive/drive_integration_service_browsertest.cc
index c19d9e4f..b00bbbc 100644
--- a/chrome/browser/ash/drive/drive_integration_service_browsertest.cc
+++ b/chrome/browser/ash/drive/drive_integration_service_browsertest.cc
@@ -27,6 +27,8 @@
 namespace drive {
 
 using ::base::test::RunClosure;
+using ::base::test::RunOnceCallback;
+using testing::_;
 
 class DriveIntegrationServiceBrowserTest : public InProcessBrowserTest {
  public:
@@ -401,18 +403,12 @@
   }
 
   void AddSyncingPath(const base::FilePath& path) {
-    auto* drive_service =
-        DriveIntegrationServiceFactory::FindForProfile(browser()->profile());
-
-    base::RunLoop run_loop;
-    auto quit_closure = run_loop.QuitClosure();
-    drive_service->ToggleSyncForPath(
-        path, drivefs::mojom::MirrorPathStatus::kStart,
-        base::BindLambdaForTesting([quit_closure](FileError status) {
-          EXPECT_EQ(FILE_ERROR_OK, status);
-          quit_closure.Run();
-        }));
-    run_loop.Run();
+    drivefs::FakeDriveFs* fake_drivefs =
+        GetFakeDriveFsForProfile(browser()->profile());
+    std::vector<base::FilePath> return_paths{path};
+    EXPECT_CALL(*fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(RunOnceCallback<0>(drive::FileError::FILE_ERROR_OK,
+                                     std::move(return_paths)));
   }
 
  private:
diff --git a/chrome/browser/ash/smb_client/smb_url.cc b/chrome/browser/ash/smb_client/smb_url.cc
index e5df0b4..1c754777 100644
--- a/chrome/browser/ash/smb_client/smb_url.cc
+++ b/chrome/browser/ash/smb_client/smb_url.cc
@@ -107,6 +107,8 @@
 }
 
 bool SmbUrl::IsValid() const {
+  // The URL is valid as long as it has a host, but some users (eg.
+  // SmbService) may also require that the share_ is defined.
   return !url_.empty() && host_.is_valid();
 }
 
@@ -127,6 +129,8 @@
     return;
   }
 
+  // Try to canonicalize the input URL into |url_|. IsValid() returns
+  // false if this is unsuccessful.
   url::StdStringCanonOutput canonical_output(&url_);
 
   url::Component scheme;
@@ -157,6 +161,7 @@
 
   canonical_output.Complete();
 
+  // |url_| is now valid, parse out any (optional) share and path component.
   if (path.is_nonempty()) {
     // Extract share name, which is the first path element.
     // Paths always start with '/', but extra '/'s are not removed.
@@ -171,6 +176,11 @@
     }
   }
 
+  // Valid SmbUrls never have trailing slashes.
+  while (url_.size() && url_.back() == '/') {
+    url_.pop_back();
+  }
+
   DCHECK(host_.is_nonempty());
   DCHECK_EQ(url_.substr(scheme.begin, scheme.len), kSmbScheme);
 }
diff --git a/chrome/browser/ash/smb_client/smb_url.h b/chrome/browser/ash/smb_client/smb_url.h
index f233327a..bdea1a0 100644
--- a/chrome/browser/ash/smb_client/smb_url.h
+++ b/chrome/browser/ash/smb_client/smb_url.h
@@ -30,10 +30,13 @@
   // Returns the host of the URL which can be resolved or unresolved.
   std::string GetHost() const;
 
-  // Returns the share component of the URL.
+  // Returns the share component of the URL. This does not have to be
+  // set for IsValid() to be true (but some clients may require it).
   std::string GetShare() const;
 
-  // Returns the full URL.
+  // Returns the full, canonicalized URL |url_| in the form
+  // smb://server/share/path (where share and path are optional). Will
+  // not have trailing slashes.
   const std::string& ToString() const;
 
   // Replaces the host to |new_host| and returns the full URL. Does not
@@ -41,7 +44,8 @@
   SmbUrl ReplaceHost(const std::string& new_host) const;
 
   // Returns true if the passed URL is valid and was properly parsed. This
-  // should be called after the constructor.
+  // should be called after the constructor. Callers should verify this
+  // before trying to use ToString(), GetHost(), GetShare() etc.
   bool IsValid() const;
 
   // Returns |url_| in the format \\server\share.
@@ -54,7 +58,7 @@
   // Parse |url| into a Windows UNC |windows_unc_|.
   void CreateWindowsUnc(const std::string& url);
 
-  // Resets url_ and parsed_.
+  // Resets url_ and parsed_. Makes the SmbUrl invalid.
   void Reset();
 
   // String form of the canonical url.
diff --git a/chrome/browser/ash/smb_client/smb_url_unittest.cc b/chrome/browser/ash/smb_client/smb_url_unittest.cc
index 8e95e6e..5a8b029 100644
--- a/chrome/browser/ash/smb_client/smb_url_unittest.cc
+++ b/chrome/browser/ash/smb_client/smb_url_unittest.cc
@@ -58,25 +58,106 @@
   ExpectInvalidUrl("\\:/host/path");
 }
 
-TEST_F(SmbUrlTest, ValidUrls) {
-  ExpectValidUrl("smb://x", "smb://x/", "x", "");
-  ExpectValidUrl("smb:///x", "smb://x/", "x", "");
-  ExpectValidUrl("smb:///x/y", "smb://x/y", "x", "y");
-  ExpectValidUrl("smb:///x/y/", "smb://x/y/", "x", "y");
-  ExpectValidUrl("smb:///x//y", "smb://x//y", "x", "");
-  ExpectValidUrl("smb:///x//y//", "smb://x//y//", "x", "");
-  ExpectValidUrl("smb://server/share/long/folder",
-                 "smb://server/share/long/folder", "server", "share");
-  ExpectValidUrl("smb://server/share/folder.with.dots",
-                 "smb://server/share/folder.with.dots", "server", "share");
-  ExpectValidUrl("smb://server\\share/mixed\\slashes",
-                 "smb://server/share/mixed/slashes", "server", "share");
-  ExpectValidUrl("\\\\server", "smb://server/", "server", "");
-  ExpectValidUrl("\\\\server/share", "smb://server/share", "server", "share");
-  ExpectValidUrl("\\\\server\\share/mixed//slashes",
-                 "smb://server/share/mixed//slashes", "server", "share");
+TEST_F(SmbUrlTest, ValidHappyPathUrls) {
+  ExpectValidUrl("smb://x", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x", "smb://x", "x", "");
+  ExpectValidUrl("smb://x/", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x\\", "smb://x", "x", "");
+
+  ExpectValidUrl("smb://x/share", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share", "smb://x/share", "x", "share");
+  ExpectValidUrl("smb://x/share/", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\", "smb://x/share", "x", "share");
+
+  // Double forward slash is not removed (except if trailing) and
+  // results in an empty share if used immediately after the host.
+  ExpectValidUrl("smb://x//path", "smb://x//path", "x", "");
+  ExpectValidUrl("\\\\x\\\\path", "smb://x//path", "x", "");
+  ExpectValidUrl("smb://x//path//long", "smb://x//path//long", "x", "");
+  ExpectValidUrl("\\\\x\\\\path\\\\long", "smb://x//path//long", "x", "");
+  ExpectValidUrl("smb://x//path//long//longer", "smb://x//path//long//longer",
+                 "x", "");
+  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\longer",
+                 "smb://x//path//long//longer", "x", "");
+
+  ExpectValidUrl("smb://x/share/path", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("smb://x/share/path/", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path\\", "smb://x/share/path", "x", "share");
+
+  ExpectValidUrl("smb://x/share/long/folder", "smb://x/share/long/folder", "x",
+                 "share");
+  ExpectValidUrl("\\\\x\\share\\long\\folder", "smb://x/share/long/folder", "x",
+                 "share");
+  ExpectValidUrl("smb://x/share/folder.with.dots",
+                 "smb://x/share/folder.with.dots", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\folder.with.dots",
+                 "smb://x/share/folder.with.dots", "x", "share");
+
   ExpectValidUrl("smb://192.168.0.1/share", "smb://192.168.0.1/share",
                  "192.168.0.1", "share");
+  ExpectValidUrl("\\\\192.168.0.1\\share", "smb://192.168.0.1/share",
+                 "192.168.0.1", "share");
+}
+
+TEST_F(SmbUrlTest, ValidWeirdSlashUrls) {
+  ExpectValidUrl("smb://x/share\\", "smb://x/share", "x", "share");
+  ExpectValidUrl("smb://x/share\\\\", "smb://x/share", "x", "share");
+  ExpectValidUrl("smb://x/share//", "smb://x/share", "x", "share");
+
+  ExpectValidUrl("smb://x\\share/mixed\\slashes", "smb://x/share/mixed/slashes",
+                 "x", "share");
+  ExpectValidUrl("\\\\x\\share/mixed\\slashes", "smb://x/share/mixed/slashes",
+                 "x", "share");
+
+  ExpectValidUrl("smb:///x", "smb://x", "x", "");
+  ExpectValidUrl("smb:///x/", "smb://x", "x", "");
+
+  ExpectValidUrl("smb:///x/share", "smb://x/share", "x", "share");
+  ExpectValidUrl("smb:///x/share/", "smb://x/share", "x", "share");
+
+  ExpectValidUrl("smb:///x//path", "smb://x//path", "x", "");
+  ExpectValidUrl("smb:///x//path//", "smb://x//path", "x", "");
+
+  ExpectValidUrl("smb:///x//path//long", "smb://x//path//long", "x", "");
+  ExpectValidUrl("smb:///x//path//long//", "smb://x//path//long", "x", "");
+}
+
+TEST_F(SmbUrlTest, TrimTrailingSlashes) {
+  ExpectValidUrl("smb://x/", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x\\", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x//", "smb://x", "x", "");
+
+  ExpectValidUrl("smb://x//", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x\\\\", "smb://x", "x", "");
+  ExpectValidUrl("\\\\x////", "smb://x", "x", "");
+
+  ExpectValidUrl("smb://x/share/", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share//", "smb://x/share", "x", "share");
+
+  ExpectValidUrl("smb://x/share//", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\\\", "smb://x/share", "x", "share");
+  ExpectValidUrl("\\\\x\\share////", "smb://x/share", "x", "share");
+
+  ExpectValidUrl("smb://x/share/path/", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path\\", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path//", "smb://x/share/path", "x", "share");
+
+  ExpectValidUrl("smb://x/share/path//", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path\\\\", "smb://x/share/path", "x", "share");
+  ExpectValidUrl("\\\\x\\share\\path////", "smb://x/share/path", "x", "share");
+
+  // Double slash after host (only) is not removed and results in an
+  // empty share.
+  ExpectValidUrl("smb://x//path//", "smb://x//path", "x", "");
+  ExpectValidUrl("\\\\x\\\\path\\\\", "smb://x//path", "x", "");
+  ExpectValidUrl("smb://x//path//long//", "smb://x//path//long", "x", "");
+  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\", "smb://x//path//long", "x", "");
+  ExpectValidUrl("smb://x//path//long//longer\\", "smb://x//path//long//longer",
+                 "x", "");
+  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\longer\\\\",
+                 "smb://x//path//long//longer", "x", "");
 }
 
 TEST_F(SmbUrlTest, NotValidIfStartsWithoutSchemeOrDoubleBackslash) {
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
index e9df4fd..1a9f6ff 100644
--- a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
@@ -12,7 +12,6 @@
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/path_service.h"
-#include "base/scoped_observation.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece_forward.h"
 #include "base/strings/stringprintf.h"
@@ -85,54 +84,6 @@
   }
 )";
 
-// Temporary observer to understand flaky test.
-// TODO(crbug.com/1328079): Remove once the root cause for the flaky test is
-// found.
-class DebugServiceWorkerContextObserver
-    : public content::ServiceWorkerContextObserver {
- public:
-  explicit DebugServiceWorkerContextObserver(Profile* profile) {
-    auto* worker_context =
-        profile->GetDefaultStoragePartition()->GetServiceWorkerContext();
-    context_observation_.Observe(worker_context);
-  }
-  ~DebugServiceWorkerContextObserver() override = default;
-
-  void OnRegistrationCompleted(const GURL& scope) override {
-    LOG(ERROR) << "Service Worker registered: " << scope;
-  }
-
-  void OnVersionActivated(int64_t version_id, const GURL& scope) override {
-    LOG(ERROR) << "Version activated:\n"
-               << "  scope: " << scope << "\n"
-               << "  version_id: " << version_id;
-  }
-
-  void OnVersionStartedRunning(
-      int64_t version_id,
-      const content::ServiceWorkerRunningInfo& running_info) override {
-    LOG(ERROR) << "Version started running:\n"
-               << "  script_url: " << running_info.script_url << "\n"
-               << "  scope: " << running_info.scope << "\n"
-               << "  version_id: " << version_id;
-  }
-
-  void OnVersionStoppedRunning(int64_t version_id) override {
-    LOG(ERROR) << "Version stopped running:\n"
-               << "  version_id: " << version_id;
-  }
-
-  void OnDestruct(content::ServiceWorkerContext* context) override {
-    LOG(ERROR) << "Context destroyed";
-    context_observation_.Reset();
-  }
-
- private:
-  base::ScopedObservation<content::ServiceWorkerContext,
-                          content::ServiceWorkerContextObserver>
-      context_observation_{this};
-};
-
 // Used to wait for a message to get added to the Service Worker console.
 // Returns the first message added to the console.
 class ServiceWorkerConsoleObserver
@@ -149,11 +100,9 @@
   // Get the first message added to the console since the observer was
   // constructed. Will wait if there are no messages yet.
   const std::u16string& WaitAndGetNextConsoleMessage() {
-    LOG(ERROR) << "Wainting for console message.";
     if (!message_.has_value())
       run_loop_.Run();
 
-    LOG(ERROR) << "Console message received.";
     return message_.value();
   }
 
@@ -276,11 +225,6 @@
 
   ~CrosWindowExtensionBrowserTest() override = default;
 
-  void SetUpOnMainThread() override {
-    debug_observer_ = std::make_unique<DebugServiceWorkerContextObserver>(
-        browser()->profile());
-  }
-
   void InstallSystemExtension() {
     auto& provider = SystemExtensionsProvider::Get(browser()->profile());
     auto& install_manager = provider.install_manager();
@@ -316,7 +260,6 @@
 
  private:
   base::test::ScopedFeatureList feature_list_;
-  std::unique_ptr<DebugServiceWorkerContextObserver> debug_observer_;
 };
 
 }  // namespace
diff --git a/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc b/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
index 87ab146..41000e6e 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
@@ -148,8 +148,6 @@
       blink::mojom::ServiceWorkerUpdateViaCache::kImports);
   blink::StorageKey key(url::Origin::Create(options.scope));
 
-  // TODO(ortuno): Remove after fixing flakiness.
-  DLOG(ERROR) << "Registering service worker";
   auto* worker_context =
       profile_->GetDefaultStoragePartition()->GetServiceWorkerContext();
   worker_context->RegisterServiceWorker(
diff --git a/chrome/browser/ash/web_applications/file_manager_web_app_info.cc b/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
index 66b1bd2..4e121906 100644
--- a/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
+++ b/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
@@ -7,7 +7,6 @@
 #include <string>
 
 #include "ash/constants/ash_features.h"
-#include "ash/style/ash_color_provider.h"
 #include "ash/webui/file_manager/resources/grit/file_manager_swa_resources.h"
 #include "ash/webui/file_manager/url_constants.h"
 #include "base/strings/utf_string_conversions.h"
@@ -70,11 +69,10 @@
       },
       *info);
 
-  auto* color_provider = ash::AshColorProvider::Get();
-  info->theme_color =
-      color_provider->GetBackgroundColorInMode(/*use_dark_color=*/false);
-  info->dark_mode_theme_color =
-      color_provider->GetBackgroundColorInMode(/*use_dark_color=*/true);
+  info->theme_color = cros_styles::ResolveColor(
+      cros_styles::ColorName::kBgColor, /*is_dark_mode=*/false);
+  info->dark_mode_theme_color = cros_styles::ResolveColor(
+      cros_styles::ColorName::kBgColor, /*is_dark_mode=*/true);
   info->background_color = info->theme_color;
   info->dark_mode_background_color = info->dark_mode_theme_color;
   info->display_mode = blink::mojom::DisplayMode::kStandalone;
diff --git a/chrome/browser/ash/web_applications/help_app/help_app_web_app_info.cc b/chrome/browser/ash/web_applications/help_app/help_app_web_app_info.cc
index ce4c688..94671de 100644
--- a/chrome/browser/ash/web_applications/help_app/help_app_web_app_info.cc
+++ b/chrome/browser/ash/web_applications/help_app/help_app_web_app_info.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "ash/constants/ash_features.h"
-#include "ash/style/ash_color_provider.h"
 #include "ash/webui/grit/ash_help_app_resources.h"
 #include "ash/webui/help_app_ui/url_constants.h"
 #include "chrome/browser/ash/web_applications/system_web_app_install_utils.h"
@@ -18,6 +17,7 @@
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/styles/cros_styles.h"
 #include "ui/display/screen.h"
 
 namespace ash {
@@ -43,11 +43,10 @@
       *info);
 
   if (chromeos::features::IsDarkLightModeEnabled()) {
-    auto* color_provider = ash::AshColorProvider::Get();
-    info->theme_color =
-        color_provider->GetBackgroundColorInMode(/*use_dark_color=*/false);
-    info->dark_mode_theme_color =
-        color_provider->GetBackgroundColorInMode(/*use_dark_color=*/true);
+    info->theme_color = cros_styles::ResolveColor(
+        cros_styles::ColorName::kBgColor, /*is_dark_mode=*/false);
+    info->dark_mode_theme_color = cros_styles::ResolveColor(
+        cros_styles::ColorName::kBgColor, /*is_dark_mode=*/true);
     info->background_color = info->theme_color;
     info->dark_mode_background_color = info->dark_mode_theme_color;
   } else {
diff --git a/chrome/browser/ash/web_applications/media_app/media_web_app_info.cc b/chrome/browser/ash/web_applications/media_app/media_web_app_info.cc
index 66f1fe5..cee8447 100644
--- a/chrome/browser/ash/web_applications/media_app/media_web_app_info.cc
+++ b/chrome/browser/ash/web_applications/media_app/media_web_app_info.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "ash/constants/ash_features.h"
-#include "ash/style/ash_color_provider.h"
 #include "ash/webui/grit/ash_media_app_resources.h"
 #include "ash/webui/media_app_ui/buildflags.h"
 #include "ash/webui/media_app_ui/url_constants.h"
@@ -26,6 +25,7 @@
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/styles/cros_styles.h"
 
 namespace {
 
@@ -177,11 +177,10 @@
   }
 
   if (chromeos::features::IsDarkLightModeEnabled()) {
-    auto* color_provider = ash::AshColorProvider::Get();
-    info->theme_color =
-        color_provider->GetBackgroundColorInMode(/*use_dark_color=*/false);
-    info->dark_mode_theme_color =
-        color_provider->GetBackgroundColorInMode(/*use_dark_color=*/true);
+    info->theme_color = cros_styles::ResolveColor(
+        cros_styles::ColorName::kBgColor, /*is_dark_mode=*/false);
+    info->dark_mode_theme_color = cros_styles::ResolveColor(
+        cros_styles::ColorName::kBgColor, /*is_dark_mode=*/true);
     info->background_color = info->theme_color;
     info->dark_mode_background_color = info->dark_mode_theme_color;
   } else {
diff --git a/chrome/browser/cart/cart_handler.cc b/chrome/browser/cart/cart_handler.cc
index 3ff361da..78b0491 100644
--- a/chrome/browser/cart/cart_handler.cc
+++ b/chrome/browser/cart/cart_handler.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "chrome/browser/cart/cart_service.h"
 #include "chrome/browser/cart/cart_service_factory.h"
+#include "chrome/browser/new_tab_page/new_tab_page_util.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "components/commerce/core/commerce_feature_list.h"
 #include "components/commerce/core/proto/cart_db_content.pb.h"
@@ -24,7 +25,7 @@
 CartHandler::~CartHandler() = default;
 
 void CartHandler::GetMerchantCarts(GetMerchantCartsCallback callback) {
-  DCHECK(base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule));
+  DCHECK(IsCartModuleEnabled());
   if (base::GetFieldTrialParamValueByFeature(
           ntp_features::kNtpChromeCartModule,
           ntp_features::kNtpChromeCartModuleDataParam) == "fake") {
diff --git a/chrome/browser/cart/cart_service.cc b/chrome/browser/cart/cart_service.cc
index 4925a3c1..6825d8b 100644
--- a/chrome/browser/cart/cart_service.cc
+++ b/chrome/browser/cart/cart_service.cc
@@ -490,10 +490,11 @@
     const GURL& cart_url,
     base::OnceCallback<void(const ::GURL&)> callback) {
   auto url = AppendUTM(cart_url);
-  if (!commerce::IsRuleDiscountPartnerMerchant(cart_url) ||
-      !IsCartDiscountEnabled()) {
+  if (commerce::IsFakeDataEnabled() || !IsCartDiscountEnabled()) {
     std::move(callback).Run(url);
-    CartDiscountMetricCollector::RecordClickedOnDiscount(false);
+    if (!commerce::IsFakeDataEnabled()) {
+      CartDiscountMetricCollector::RecordClickedOnDiscount(false);
+    }
     return;
   }
   LoadCart(eTLDPlusOne(cart_url), base::BindOnce(&CartService::OnGetDiscountURL,
@@ -515,8 +516,12 @@
   auto& cart_proto = proto_pairs[0].second;
   if (!IsCartDiscountEnabled() ||
       cart_proto.discount_info().rule_discount_info().empty()) {
+    if (cart_proto.discount_info().has_coupons()) {
+      CartDiscountMetricCollector::RecordClickedOnDiscount(true);
+    } else {
+      CartDiscountMetricCollector::RecordClickedOnDiscount(false);
+    }
     std::move(callback).Run(default_cart_url);
-    CartDiscountMetricCollector::RecordClickedOnDiscount(false);
     return;
   }
   auto pending_factory = profile_->GetDefaultStoragePartition()
diff --git a/chrome/browser/cart/cart_service_unittest.cc b/chrome/browser/cart/cart_service_unittest.cc
index 2a5b4bc..aa407c4 100644
--- a/chrome/browser/cart/cart_service_unittest.cc
+++ b/chrome/browser/cart/cart_service_unittest.cc
@@ -76,6 +76,16 @@
   return proto;
 }
 
+cart_db::ChromeCartContentProto AddCouponDiscountToProto(
+    cart_db::ChromeCartContentProto proto,
+    const double timestamp,
+    const char* discount_text) {
+  proto.mutable_discount_info()->set_last_fetched_timestamp(timestamp);
+  proto.mutable_discount_info()->set_discount_text(discount_text);
+  proto.mutable_discount_info()->set_has_coupons(true);
+  return proto;
+}
+
 MATCHER_P(EqualsProto, message, "") {
   std::string expected_serialized, actual_serialized;
   message.SerializeToString(&expected_serialized);
@@ -1503,12 +1513,9 @@
 // merchant.
 TEST_F(CartServiceDiscountTest, TestNoFetchForNonPartner) {
   base::RunLoop run_loop[2];
-  const double timestamp = 1;
   SetCartDiscountURLForTesting(GURL("https://www.discount.com"), false);
-  cart_db::ChromeCartContentProto cart_proto = AddDiscountToProto(
-      BuildProto(kMockMerchantB, kMockMerchantURLB), timestamp,
-      kMockMerchantADiscountRuleId, kMockMerchantADiscountsPercentOff,
-      kMockMerchantADiscountsRawMerchantOfferId);
+  cart_db::ChromeCartContentProto cart_proto =
+      BuildProto(kMockMerchantB, kMockMerchantURLB);
   service_->GetDB()->AddCart(
       kMockMerchantB, cart_proto,
       base::BindOnce(&CartServiceTest::OperationEvaluation,
@@ -1522,6 +1529,10 @@
                      base::Unretained(this), run_loop[1].QuitClosure(),
                      default_cart_url));
   run_loop[1].Run();
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      false, 1);
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      true, 0);
 }
 
 // Tests no fetching for discount URL if the cart doesn't have discount info.
@@ -1541,6 +1552,10 @@
                      base::Unretained(this), run_loop[1].QuitClosure(),
                      default_cart_url));
   run_loop[1].Run();
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      false, 1);
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      true, 0);
 }
 
 // Tests no fetching for discount URL if the feature is disabled.
@@ -1567,6 +1582,38 @@
                      base::Unretained(this), run_loop[1].QuitClosure(),
                      default_cart_url));
   run_loop[1].Run();
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      false, 1);
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      true, 0);
+}
+
+// Tests no fetching discounted URL for coupon discount.
+TEST_F(CartServiceDiscountTest, TestNoDiscountedURLFetchForCouponDiscount) {
+  base::RunLoop run_loop[2];
+  const double timestamp = 1;
+  GURL discount_url("https://www.discount.com");
+  SetCartDiscountURLForTesting(discount_url, /*expect_call=*/false);
+  cart_db::ChromeCartContentProto cart_proto = AddCouponDiscountToProto(
+      BuildProto(kMockMerchantA, kMockMerchantURLA), timestamp,
+      /*discount_text=*/"10% off");
+  service_->GetDB()->AddCart(
+      kMockMerchantA, cart_proto,
+      base::BindOnce(&CartServiceTest::OperationEvaluation,
+                     base::Unretained(this), run_loop[0].QuitClosure(), true));
+  run_loop[0].Run();
+
+  GURL default_cart_url(kMockMerchantURLA);
+  service_->GetDiscountURL(
+      default_cart_url,
+      base::BindOnce(&CartServiceTest::GetEvaluationDiscountURL,
+                     base::Unretained(this), run_loop[1].QuitClosure(),
+                     default_cart_url));
+  run_loop[1].Run();
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      false, 0);
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      true, 1);
 }
 
 // Tests CartService returning fetched discount URL.
@@ -1606,6 +1653,10 @@
       base::BindOnce(&CartServiceTest::GetEvaluationEmptyDiscount,
                      base::Unretained(this), run_loop[3].QuitClosure()));
   run_loop[3].Run();
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      false, 0);
+  histogram_tester_.ExpectBucketCount("NewTabPage.Carts.ClickCart.HasDiscount",
+                                      true, 1);
 }
 
 // Tests CartService returning original cart URL as a fallback if the fetch
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 171c42f..513698d 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -647,7 +647,7 @@
   // We should not request this mojo interface's binding for the subframes in
   // the renderer.
 #if !BUILDFLAG(IS_ANDROID)
-  if (base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule) &&
+  if (IsCartModuleEnabled() &&
 #else
   if (base::FeatureList::IsEnabled(commerce::kCommerceHintAndroid) &&
 #endif
@@ -899,7 +899,7 @@
       map);
 #endif  // !defined(OFFICIAL_BUILD)
 
-  if (base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule)) {
+  if (IsCartModuleEnabled()) {
     RegisterWebUIControllerInterfaceBinder<chrome_cart::mojom::CartHandler,
                                            NewTabPageUI>(map);
   }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 0877cc6..4862927 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -443,6 +443,7 @@
 #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/media/unified_autoplay_config.h"
+#include "chrome/browser/new_tab_page/new_tab_page_util.h"
 #include "chrome/browser/page_info/about_this_site_side_panel_throttle.h"
 #include "chrome/browser/search/instant_service.h"
 #include "chrome/browser/search/instant_service_factory.h"
@@ -459,6 +460,7 @@
 #include "chrome/browser/webauthn/authenticator_request_scheduler.h"
 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
 #include "chrome/grit/chrome_unscaled_resources.h"  // nogncheck crbug.com/1125897
+#include "components/commerce/core/commerce_feature_list.h"
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
 #endif  //  !BUILDFLAG(IS_ANDROID)
 
@@ -2520,6 +2522,10 @@
               webauthn::pref_names::kRemoteProxiedRequestsAllowed)) {
         command_line->AppendSwitch(switches::kWebAuthRemoteDesktopSupport);
       }
+
+      if (IsCartModuleEnabled()) {
+        command_line->AppendSwitch(commerce::switches::kEnableChromeCart);
+      }
 #endif
     }
 
@@ -3812,7 +3818,6 @@
     web_prefs->text_track_font_family = style->font_family;
     web_prefs->text_track_font_variant = style->font_variant;
     web_prefs->text_track_window_color = style->window_color;
-    web_prefs->text_track_window_padding = style->window_padding;
     web_prefs->text_track_window_radius = style->window_radius;
   }
 
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
index 31cbc7e4..d2923ff5 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
+++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
@@ -116,7 +116,8 @@
     if (pref_value_map.GetValue(extensions::pref_names::kInstallForceList,
                                 &value) &&
         value->GetAsDictionary(&dict)) {
-      prefs.reset(dict->DeepCopy());
+      prefs = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(dict->Clone()));
     }
   }
 
diff --git a/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
index ee24830..f4c01168 100644
--- a/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
+++ b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
@@ -71,7 +71,8 @@
 
   // ExternalCacheDelegate:
   void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override {
-    prefs_.reset(prefs->DeepCopy());
+    prefs_ = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(prefs->Clone()));
   }
 
   void OnCachedExtensionFileDeleted(
diff --git a/chrome/browser/component_updater/commerce_heuristics_component_installer.cc b/chrome/browser/component_updater/commerce_heuristics_component_installer.cc
index f59e9a0..37aff983 100644
--- a/chrome/browser/component_updater/commerce_heuristics_component_installer.cc
+++ b/chrome/browser/component_updater/commerce_heuristics_component_installer.cc
@@ -19,6 +19,7 @@
 #include "components/commerce/core/commerce_heuristics_data.h"
 #include "components/component_updater/component_updater_paths.h"
 #if !BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/new_tab_page/new_tab_page_util.h"
 #include "components/search/ntp_features.h"
 #else
 #include "components/commerce/core/commerce_feature_list.h"
@@ -187,7 +188,7 @@
 void RegisterCommerceHeuristicsComponent(
     component_updater::ComponentUpdateService* cus) {
 #if !BUILDFLAG(IS_ANDROID)
-  if (base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule)) {
+  if (IsCartModuleEnabled()) {
 #else
   if (base::FeatureList::IsEnabled(commerce::kCommerceHintAndroid)) {
 #endif
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc
index 2f261aa9..2c95d52a 100644
--- a/chrome/browser/extensions/api/commands/command_service.cc
+++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -82,7 +82,9 @@
   if (extension_prefs->ReadPrefAsDictionary(extension_id,
                                             kCommands,
                                             &current_prefs)) {
-    std::unique_ptr<base::DictionaryValue> new_prefs(current_prefs->DeepCopy());
+    std::unique_ptr<base::DictionaryValue> new_prefs =
+        base::DictionaryValue::From(
+            base::Value::ToUniquePtrValue(current_prefs->Clone()));
     new_prefs->MergeDictionary(suggested_key_prefs.get());
     suggested_key_prefs = std::move(new_prefs);
   }
@@ -558,8 +560,9 @@
                                         &current_prefs);
 
   if (current_prefs) {
-    std::unique_ptr<base::DictionaryValue> suggested_key_prefs(
-        current_prefs->DeepCopy());
+    std::unique_ptr<base::DictionaryValue> suggested_key_prefs =
+        base::DictionaryValue::From(
+            base::Value::ToUniquePtrValue(current_prefs->Clone()));
     const CommandMap* named_commands =
         CommandsInfo::GetNamedCommands(extension);
 
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
index 44a8dd8..7b10f05 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -270,7 +270,9 @@
                                        .Build())
           .Set("permissions", ListBuilder().Append("tabs").Build())
           .Build();
-  std::unique_ptr<base::DictionaryValue> manifest_copy(manifest->DeepCopy());
+  std::unique_ptr<base::DictionaryValue> manifest_copy =
+      base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(manifest->Clone()));
   scoped_refptr<const Extension> extension =
       ExtensionBuilder()
           .SetManifest(std::move(manifest))
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 fba63311d..de2382a2 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -4990,4 +4990,266 @@
                          WebRequestApiTestWithContextType,
                          ::testing::Values(ContextType::kServiceWorker));
 
+class ManifestV3WebRequestApiTest : public ExtensionWebRequestApiTest {
+ public:
+  ManifestV3WebRequestApiTest() = default;
+  ~ManifestV3WebRequestApiTest() override = default;
+
+  // Loads an extension contained within `test_dir` as a policy-installed
+  // extension. This is useful because webRequestBlocking is restricted to
+  // policy-installed extensions in Manifest V3.
+  // This assumes the extension script will send a "ready" message once it's
+  // done setting up.
+  const Extension* LoadPolicyExtension(TestExtensionDir& test_dir) {
+    // We need a "ready"-style listener here because `InstallExtension()`
+    // doesn't automagically wait for the extension to finish setting up.
+    ExtensionTestMessageListener listener("ready");
+    // Since we may programmatically stop the worker, we also need to wait for
+    // the registration to be fully stored.
+    service_worker_test_utils::TestRegistrationObserver registration_observer(
+        profile());
+    base::FilePath packed_path = test_dir.Pack();
+    const Extension* extension = InstallExtension(
+        packed_path, 1, mojom::ManifestLocation::kExternalPolicyDownload);
+    EXPECT_TRUE(extension);
+    EXPECT_TRUE(listener.WaitUntilSatisfied());
+    registration_observer.WaitForRegistrationStored();
+
+    return extension;
+  }
+
+  ExtensionWebRequestEventRouter* web_request_router() {
+    return ExtensionWebRequestEventRouter::GetInstance();
+  }
+};
+
+// Tests a service worker-based extension intercepting requests with
+// webRequestBlocking.
+IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, WebRequestBlocking) {
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  static constexpr char kManifest[] =
+      R"({
+           "name": "MV3 WebRequest",
+           "version": "0.1",
+           "manifest_version": 3,
+           "permissions": ["webRequest", "webRequestBlocking"],
+           "host_permissions": [
+             "http://block.example/*",
+             "http://allow.example/*"
+           ],
+           "background": {"service_worker": "background.js"}
+         })";
+  // An extension with a listener that cancels any requests that include
+  // block.example.
+  static constexpr char kBackgroundJs[] =
+      R"(chrome.webRequest.onBeforeRequest.addListener(
+             (details) => {
+               if (details.url.includes('block.example')) {
+                 return {cancel: true}
+               }
+               return {};
+             },
+             {urls: ['<all_urls>'], types: ['main_frame']},
+             ['blocking']);
+         chrome.test.sendMessage('ready');)";
+
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifest);
+  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
+  const Extension* extension = LoadPolicyExtension(test_dir);
+  ASSERT_TRUE(extension);
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Navigate to allow.example. This should succeed.
+  {
+    content::TestNavigationObserver nav_observer(web_contents);
+    EXPECT_TRUE(ui_test_utils::NavigateToURL(
+        browser(),
+        embedded_test_server()->GetURL("allow.example", "/simple.html")));
+    EXPECT_EQ(net::OK, nav_observer.last_net_error_code());
+  }
+
+  // Now, navigate to block.example. This navigation should be blocked.
+  {
+    content::TestNavigationObserver nav_observer(web_contents);
+    EXPECT_TRUE(ui_test_utils::NavigateToURL(
+        browser(),
+        embedded_test_server()->GetURL("block.example", "/simple.html")));
+    EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, nav_observer.last_net_error_code());
+  }
+}
+
+// Tests that a service worker-based extension with webRequestBlocking can
+// intercept requests after the service worker stops.
+IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
+                       WebRequestBlocking_AfterWorkerShutdown) {
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  static constexpr char kManifest[] =
+      R"({
+           "name": "MV3 WebRequest",
+           "version": "0.1",
+           "manifest_version": 3,
+           "permissions": ["webRequest", "webRequestBlocking"],
+           "host_permissions": [
+             "http://block.example/*"
+           ],
+           "background": {"service_worker": "background.js"}
+         })";
+  // An extension with a listener that cancels any requests that include
+  // block.example.
+  static constexpr char kBackgroundJs[] =
+      R"(chrome.webRequest.onBeforeRequest.addListener(
+             (details) => {
+               if (details.url.includes('block.example')) {
+                 return {cancel: true}
+               }
+               return {};
+             },
+             {urls: ['<all_urls>'], types: ['main_frame']},
+             ['blocking']);
+         chrome.test.sendMessage('ready');)";
+
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifest);
+  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
+  const Extension* extension = LoadPolicyExtension(test_dir);
+  ASSERT_TRUE(extension);
+
+  // A single webRequest listener should be registered.
+  EXPECT_EQ(1u, web_request_router()->GetListenerCountForTesting(
+                    profile(), "webRequest.onBeforeRequest"));
+
+  // Stop the service worker.
+  browsertest_util::StopServiceWorkerForExtensionGlobalScope(profile(),
+                                                             extension->id());
+  // Note: the task to remove listeners from ExtensionWebRequestEventRouter
+  // is async; run to flush the posted task.
+  base::RunLoop().RunUntilIdle();
+
+  // The listener should still be registered.
+  // TODO(https://crbug.com/1024211): This currently fails.
+  // EXPECT_EQ(1u, web_request_router()->GetListenerCountForTesting(
+  //     profile(), "webRequest.onBeforeRequest"));
+  EXPECT_EQ(0u, web_request_router()->GetListenerCountForTesting(
+                    profile(), "webRequest.onBeforeRequest"));
+
+  // Navigate to block.example. The request should be blocked by the extension.
+  {
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    content::TestNavigationObserver nav_observer(web_contents);
+    EXPECT_TRUE(ui_test_utils::NavigateToURL(
+        browser(),
+        embedded_test_server()->GetURL("block.example", "/simple.html")));
+    // TODO(https://crbug.com/1024211): This currently fails.
+    // EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT,
+    //           nav_observer.last_net_error_code());
+    EXPECT_EQ(net::OK, nav_observer.last_net_error_code());
+  }
+}
+
+// Tests a service worker-based extension using webRequest for observational
+// purposes receives events after the worker stops.
+IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest,
+                       WebRequestObservation_AfterWorkerShutdown) {
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  static constexpr char kManifest[] =
+      R"({
+           "name": "MV3 WebRequest",
+           "version": "0.1",
+           "manifest_version": 3,
+           "permissions": ["webRequest", "storage"],
+           "host_permissions": [
+             "http://example.com/*"
+           ],
+           "background": {"service_worker": "background.js"}
+         })";
+  // An extension that stores the number of matched requests in a count in
+  // extension storage.
+  // This is very similar to the test extension at
+  // chrome/test/data/extensions/api_test/webrequest_persistent, but is
+  // manifest V3. There's enough changes that our loading auto-conversion code
+  // won't quite work (mostly around permissions vs host_permissions), so we
+  // need a bit of a duplication here.
+  static constexpr char kBackgroundJs[] =
+      R"(let storageComplete = undefined;
+         let isUsingStorage = false;
+
+         // Waits for any pending load to complete to avoid raciness in the
+         // test.
+         async function flushStorage() {
+           console.assert(!storageComplete);
+           if (!isUsingStorage)
+             return;
+           await new Promise((resolve) => {
+             storageComplete = resolve;
+           });
+           storageComplete = undefined;
+         }
+
+         chrome.webRequest.onBeforeRequest.addListener(
+             async (details) => {
+               isUsingStorage = true;
+               let {requestCount} =
+                   await chrome.storage.local.get({requestCount: 0});
+               requestCount++;
+               await chrome.storage.local.set({requestCount});
+               isUsingStorage = false;
+               if (storageComplete)
+                 storageComplete();
+             },
+             {urls: ['<all_urls>'], types: ['main_frame']});)";
+
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifest);
+  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
+  const Extension* extension = LoadExtension(
+      test_dir.UnpackedPath(), {.wait_for_registration_stored = true});
+  ASSERT_TRUE(extension);
+
+  // A single listener should be registered.
+  EXPECT_EQ(1u, web_request_router()->GetListenerCountForTesting(
+                    profile(), "webRequest.onBeforeRequest"));
+
+  // Navigate to a URL. The request should be seen by the extension.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(),
+      embedded_test_server()->GetURL("example.com", "/simple.html")));
+
+  auto get_request_count = [this, extension]() {
+    base::Value request_count = BackgroundScriptExecutor::ExecuteScript(
+        profile(), extension->id(), kGetNumRequests,
+        BackgroundScriptExecutor::ResultCapture::kSendScriptResult);
+    return request_count.GetInt();
+  };
+
+  EXPECT_EQ(1, get_request_count());
+
+  // Stop the extension's service worker.
+  browsertest_util::StopServiceWorkerForExtensionGlobalScope(profile(),
+                                                             extension->id());
+  // Note: the task to remove listeners from ExtensionWebRequestEventRouter
+  // is async; run to flush the posted task.
+  base::RunLoop().RunUntilIdle();
+
+  // The listener should still be registered.
+  // TODO(https://crbug.com/1024211): This currently fails.
+  // EXPECT_EQ(1u, web_request_router()->GetListenerCountForTesting(
+  //     profile(), "webRequest.onBeforeRequest"));
+  EXPECT_EQ(0u, web_request_router()->GetListenerCountForTesting(
+                    profile(), "webRequest.onBeforeRequest"));
+
+  // Navigate again. The request should again be seen by the extension.
+  EXPECT_TRUE(ui_test_utils::NavigateToURL(
+      browser(),
+      embedded_test_server()->GetURL("example.com", "/simple.html")));
+
+  // TODO(https://crbug.com/1024211): This currently fails. Additionally,
+  // BackgroundScriptExecutor won't wake up a passive service worker, so
+  // we can't even call `get_request_count()`.
+  // EXPECT_EQ(2, get_request_count());
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index 4a09461..c0e6577 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/app_list/app_list_util.h"
 #include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
@@ -871,7 +872,7 @@
 void WebstorePrivateBeginInstallWithManifest3Function::
     ShowInstallFrictionDialog(content::WebContents* contents) {
   friction_dialog_shown_ = true;
-  chrome::ShowExtensionInstallFrictionDialog(
+  ShowExtensionInstallFrictionDialog(
       contents,
       base::BindOnce(&WebstorePrivateBeginInstallWithManifest3Function::
                          OnFrictionPromptDone,
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 9301e54..3c900f86 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -521,7 +521,8 @@
   {
     scoped_refptr<const Extension> extension =
         ExtensionBuilder()
-            .SetManifest(base::WrapUnique(manifest->DeepCopy()))
+            .SetManifest(base::DictionaryValue::From(
+                base::Value::ToUniquePtrValue(manifest->Clone())))
             .SetID(crx_file::id_util::GenerateId("component"))
             .SetLocation(ManifestLocation::kComponent)
             .Build();
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 339ae3f8..65835e3 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -483,7 +483,8 @@
     std::string* error) {
   std::unique_ptr<base::DictionaryValue> localized_manifest;
   if (!localized_name.empty() || !localized_description.empty()) {
-    localized_manifest.reset(manifest->DeepCopy());
+    localized_manifest = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(manifest->Clone()));
     if (!localized_name.empty()) {
       localized_manifest->SetStringKey(extensions::manifest_keys::kName,
                                        localized_name);
diff --git a/chrome/browser/extensions/extension_management_test_util.cc b/chrome/browser/extensions/extension_management_test_util.cc
index b780f9d..08dfeaf 100644
--- a/chrome/browser/extensions/extension_management_test_util.cc
+++ b/chrome/browser/extensions/extension_management_test_util.cc
@@ -302,8 +302,9 @@
 
 // Private section functions ---------------------------------------------------
 
-void ExtensionManagementPrefUpdaterBase::SetPref(base::DictionaryValue* pref) {
-  pref_.reset(pref);
+void ExtensionManagementPrefUpdaterBase::SetPref(
+    std::unique_ptr<base::DictionaryValue> pref) {
+  pref_.reset(pref.release());
 }
 
 std::unique_ptr<base::DictionaryValue>
@@ -348,11 +349,12 @@
           ->Get(policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
                                         std::string()))
           .GetValue(policy::key::kExtensionSettings, base::Value::Type::DICT);
-  const base::DictionaryValue* dict_value = nullptr;
-  if (policy_value && policy_value->GetAsDictionary(&dict_value))
-    SetPref(dict_value->DeepCopy());
-  else
-    SetPref(new base::DictionaryValue);
+  std::unique_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
+  if (policy_value && policy_value->is_dict()) {
+    dict_value = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(policy_value->Clone()));
+  }
+  SetPref(std::move(dict_value));
 }
 
 ExtensionManagementPolicyUpdater::~ExtensionManagementPolicyUpdater() {
diff --git a/chrome/browser/extensions/extension_management_test_util.h b/chrome/browser/extensions/extension_management_test_util.h
index e8dc48a..b959184 100644
--- a/chrome/browser/extensions/extension_management_test_util.h
+++ b/chrome/browser/extensions/extension_management_test_util.h
@@ -110,7 +110,7 @@
   // Set the preference with |pref|, pass the ownership of it as well.
   // This function must be called before accessing publicly exposed functions,
   // for example in constructor of subclass.
-  void SetPref(base::DictionaryValue* pref);
+  void SetPref(std::unique_ptr<base::DictionaryValue> pref);
 
   // Take the preference. Caller takes ownership of it as well.
   // This function must be called after accessing publicly exposed functions,
@@ -136,11 +136,13 @@
       : service_(service) {
     const base::Value* pref_value =
         service_->GetManagedPref(pref_names::kExtensionManagement);
-    const base::DictionaryValue* dict_value = nullptr;
-    if (pref_value && pref_value->GetAsDictionary(&dict_value))
-      SetPref(dict_value->DeepCopy());
-    else
-      SetPref(new base::DictionaryValue);
+    std::unique_ptr<base::DictionaryValue> dict_value(
+        new base::DictionaryValue);
+    if (pref_value && pref_value->is_dict()) {
+      dict_value = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(pref_value->Clone()));
+    }
+    SetPref(std::move(dict_value));
   }
 
   ExtensionManagementPrefUpdater(const ExtensionManagementPrefUpdater&) =
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index 37b0cc6..2ead222ac 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -402,9 +402,9 @@
         continue;
       }
 
-      extensions_info->at(i)->extension_manifest.reset(
-          static_cast<base::DictionaryValue*>(
-              extension->manifest()->value()->DeepCopy()));
+      extensions_info->at(i)->extension_manifest =
+          base::DictionaryValue::From(base::Value::ToUniquePtrValue(
+              extension->manifest()->value()->Clone()));
       should_write_prefs = true;
     }
   }
diff --git a/chrome/browser/extensions/webstore_installer_browsertest.cc b/chrome/browser/extensions/webstore_installer_browsertest.cc
index e18db1c..2bd41a3 100644
--- a/chrome/browser/extensions/webstore_installer_browsertest.cc
+++ b/chrome/browser/extensions/webstore_installer_browsertest.cc
@@ -170,7 +170,9 @@
   std::unique_ptr<WebstoreInstaller::Approval> approval =
       WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
           browser()->profile(), kTestExtensionId,
-          std::unique_ptr<base::DictionaryValue>(manifest->DeepCopy()), false);
+          base::DictionaryValue::From(
+              base::Value::ToUniquePtrValue(manifest->Clone())),
+          false);
 
   // Create and run a WebstoreInstaller.
   base::RunLoop run_loop;
diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc
index 254faa3..913188d 100644
--- a/chrome/browser/extensions/webstore_standalone_installer.cc
+++ b/chrome/browser/extensions/webstore_standalone_installer.cc
@@ -173,7 +173,9 @@
   std::unique_ptr<WebstoreInstaller::Approval> approval(
       WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
           profile_, id_,
-          std::unique_ptr<base::DictionaryValue>(manifest_->DeepCopy()), true));
+          base::DictionaryValue::From(
+              base::Value::ToUniquePtrValue(manifest_->Clone())),
+          true));
   approval->skip_post_install_ui = !ShouldShowPostInstallUI();
   approval->use_app_installed_bubble = ShouldShowAppInstalledBubble();
   approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_);
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
index 54ca655..1006e14 100644
--- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/metrics/variations/ui_string_overrider_factory.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/ui/browser_otr_state.h"
-#include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/installer/util/google_update_settings.h"
@@ -34,7 +33,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/variations/service/variations_service.h"
 #include "components/variations/variations_associated_data.h"
-#include "components/version_info/channel.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/network_service_instance.h"
@@ -311,7 +309,7 @@
 
     metrics_state_manager_ = metrics::MetricsStateManager::Create(
         local_state_, enabled_state_provider_.get(), GetRegistryBackupKey(),
-        user_data_dir, startup_visibility, chrome::GetChannel(),
+        user_data_dir, startup_visibility,
         base::BindRepeating(&PostStoreMetricsClientInfo),
         base::BindRepeating(&GoogleUpdateSettings::LoadMetricsClientInfo),
         client_id);
diff --git a/chrome/browser/metrics/variations/variations_safe_mode_end_to_end_browsertest.cc b/chrome/browser/metrics/variations/variations_safe_mode_end_to_end_browsertest.cc
index 85998f2..0e3156e 100644
--- a/chrome/browser/metrics/variations/variations_safe_mode_end_to_end_browsertest.cc
+++ b/chrome/browser/metrics/variations/variations_safe_mode_end_to_end_browsertest.cc
@@ -37,7 +37,6 @@
 #include "components/variations/service/variations_service.h"
 #include "components/variations/variations_switches.h"
 #include "components/variations/variations_test_utils.h"
-#include "components/version_info/channel.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -171,8 +170,7 @@
       PrefService* pref_service) {
     static constexpr wchar_t kDummyWindowsRegistryKey[] = L"";
     auto clean_exit_beacon = std::make_unique<metrics::CleanExitBeacon>(
-        kDummyWindowsRegistryKey, user_data_dir(), pref_service,
-        version_info::Channel::UNKNOWN);
+        kDummyWindowsRegistryKey, user_data_dir(), pref_service);
     clean_exit_beacon->Initialize();
     return clean_exit_beacon;
   }
diff --git a/chrome/browser/new_tab_page/new_tab_page_util.cc b/chrome/browser/new_tab_page/new_tab_page_util.cc
index 723af97..8dcf182 100644
--- a/chrome/browser/new_tab_page/new_tab_page_util.cc
+++ b/chrome/browser/new_tab_page/new_tab_page_util.cc
@@ -10,7 +10,7 @@
 #include "components/variations/service/variations_service.h"
 
 namespace {
-bool IsOsSupported() {
+bool IsOsSupportedForRecipe() {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
   return true;
 #else
@@ -18,6 +18,14 @@
 #endif
 }
 
+bool IsOsSupportedForCart() {
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
+  return true;
+#else
+  return false;
+#endif
+}
+
 std::string GetCountryCode() {
   std::string country_code;
   auto* variations_service = g_browser_process->variations_service();
@@ -27,6 +35,11 @@
   return country_code.empty() ? variations_service->GetLatestCountry()
                               : country_code;
 }
+
+bool IsInUS() {
+  return g_browser_process->GetApplicationLocale() == "en-US" &&
+         GetCountryCode() == "us";
+}
 }  // namespace
 
 // If feature is overridden manually or by finch, read the feature flag value.
@@ -36,8 +49,15 @@
           ntp_features::kNtpRecipeTasksModule.name)) {
     return base::FeatureList::IsEnabled(ntp_features::kNtpRecipeTasksModule);
   } else {
-    return IsOsSupported() &&
-           g_browser_process->GetApplicationLocale() == "en-US" &&
-           GetCountryCode() == "us";
+    return IsOsSupportedForRecipe() && IsInUS();
+  }
+}
+
+bool IsCartModuleEnabled() {
+  if (base::FeatureList::GetInstance()->IsFeatureOverridden(
+          ntp_features::kNtpChromeCartModule.name)) {
+    return base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule);
+  } else {
+    return IsOsSupportedForCart() && IsInUS();
   }
 }
diff --git a/chrome/browser/new_tab_page/new_tab_page_util.h b/chrome/browser/new_tab_page/new_tab_page_util.h
index fe54408..7a6a1457 100644
--- a/chrome/browser/new_tab_page/new_tab_page_util.h
+++ b/chrome/browser/new_tab_page/new_tab_page_util.h
@@ -6,5 +6,6 @@
 #define CHROME_BROWSER_NEW_TAB_PAGE_NEW_TAB_PAGE_UTIL_H_
 
 bool IsRecipeTasksModuleEnabled();
+bool IsCartModuleEnabled();
 
 #endif  // CHROME_BROWSER_NEW_TAB_PAGE_NEW_TAB_PAGE_UTIL_H_
diff --git a/chrome/browser/new_tab_page/new_tab_page_util_browsertest.cc b/chrome/browser/new_tab_page/new_tab_page_util_browsertest.cc
index 6e2b6fe..b0819ef 100644
--- a/chrome/browser/new_tab_page/new_tab_page_util_browsertest.cc
+++ b/chrome/browser/new_tab_page/new_tab_page_util_browsertest.cc
@@ -20,18 +20,21 @@
 class NewTabPageUtilEnableFlagBrowserTest : public NewTabPageUtilBrowserTest {
  public:
   NewTabPageUtilEnableFlagBrowserTest() {
-    features_.InitWithFeatures({ntp_features::kNtpRecipeTasksModule}, {});
+    features_.InitWithFeatures({ntp_features::kNtpRecipeTasksModule,
+                                ntp_features::kNtpChromeCartModule},
+                               {});
   }
 };
 
 class NewTabPageUtilDisableFlagBrowserTest : public NewTabPageUtilBrowserTest {
  public:
   NewTabPageUtilDisableFlagBrowserTest() {
-    features_.InitWithFeatures({}, {ntp_features::kNtpRecipeTasksModule});
+    features_.InitWithFeatures({}, {ntp_features::kNtpRecipeTasksModule,
+                                    ntp_features::kNtpChromeCartModule});
   }
 };
 
-IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, EnableByToT) {
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, EnableRecipesByToT) {
   auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
   g_browser_process->variations_service()->OverrideStoredPermanentCountry("us");
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
@@ -41,18 +44,47 @@
 #endif
 }
 
-IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, DisableByToT) {
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, DisableRecipesByToT) {
   auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
   g_browser_process->variations_service()->OverrideStoredPermanentCountry("ca");
   EXPECT_FALSE(IsRecipeTasksModuleEnabled());
 }
 
-IN_PROC_BROWSER_TEST_F(NewTabPageUtilEnableFlagBrowserTest, EnableByFlag) {
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilEnableFlagBrowserTest,
+                       EnableRecipesByFlag) {
   EXPECT_TRUE(IsRecipeTasksModuleEnabled());
 }
 
-IN_PROC_BROWSER_TEST_F(NewTabPageUtilDisableFlagBrowserTest, DisableByFlag) {
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilDisableFlagBrowserTest,
+                       DisableRecipesByFlag) {
   auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
   g_browser_process->variations_service()->OverrideStoredPermanentCountry("us");
   EXPECT_FALSE(IsRecipeTasksModuleEnabled());
 }
+
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, EnableCartByToT) {
+  auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
+  g_browser_process->variations_service()->OverrideStoredPermanentCountry("us");
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
+  EXPECT_TRUE(IsCartModuleEnabled());
+#else
+  EXPECT_FALSE(IsCartModuleEnabled());
+#endif
+}
+
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilBrowserTest, DisableCartByToT) {
+  auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
+  g_browser_process->variations_service()->OverrideStoredPermanentCountry("ca");
+  EXPECT_FALSE(IsCartModuleEnabled());
+}
+
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilEnableFlagBrowserTest, EnableCartByFlag) {
+  EXPECT_TRUE(IsCartModuleEnabled());
+}
+
+IN_PROC_BROWSER_TEST_F(NewTabPageUtilDisableFlagBrowserTest,
+                       DisableCartByFlag) {
+  auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
+  g_browser_process->variations_service()->OverrideStoredPermanentCountry("us");
+  EXPECT_FALSE(IsCartModuleEnabled());
+}
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 7fecef7..f582a11 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -153,7 +153,7 @@
   DummyLogReceiver(const DummyLogReceiver&) = delete;
   DummyLogReceiver& operator=(const DummyLogReceiver&) = delete;
 
-  void LogEntry(const base::Value& entry) override {}
+  void LogEntry(const base::Value::Dict& entry) override {}
 };
 
 class FakePasswordAutofillAgent
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.h b/chrome/browser/policy/messaging_layer/public/report_client.h
index d4b65eca..f6f3b27 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.h
+++ b/chrome/browser/policy/messaging_layer/public/report_client.h
@@ -84,7 +84,7 @@
   // retrieval for downstream processing, and triggers the corresponding
   // completion callback with the updated config.
   void ConfigureReportQueue(
-      std::unique_ptr<reporting::ReportQueueConfiguration> report_queue_config,
+      std::unique_ptr<ReportQueueConfiguration> report_queue_config,
       ReportQueueProvider::ReportQueueConfiguredCallback completion_cb)
       override;
 
diff --git a/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc
index 8ad6ff14..1ce4a2f 100644
--- a/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc
+++ b/chrome/browser/policy/messaging_layer/upload/event_upload_size_controller.cc
@@ -69,12 +69,11 @@
 }
 
 // static
-std::vector<reporting::EncryptedRecord>
-EventUploadSizeController::BuildEncryptedRecords(
+std::vector<EncryptedRecord> EventUploadSizeController::BuildEncryptedRecords(
     const google::protobuf::RepeatedPtrField<EncryptedRecord>&
         encrypted_records,
     EventUploadSizeController&& controller) {
-  std::vector<reporting::EncryptedRecord> records;
+  std::vector<EncryptedRecord> records;
   for (auto& record : encrypted_records) {
     // Check if we have uploaded enough records after adding each record
     controller.AccountForRecord(record);
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
index 37e5f077..47c5fea 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
@@ -194,7 +194,7 @@
              ReportingServerConnector::ResponseCallback response_cb) {
             ReportingServerConnector::UploadEncryptedReport(
                 std::move(request),
-                reporting::GetContext(ProfileManager::GetPrimaryUserProfile()),
+                GetContext(ProfileManager::GetPrimaryUserProfile()),
                 std::move(response_cb));
           },
           std::move(request_result.value()), std::move(response_cb)));
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
index b549075..99cb3e63 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
@@ -62,23 +62,13 @@
             report_successful_upload_cb,
             encryption_key_attached_cb,
             /*upload_client_builder_cb=*/
-            base::BindRepeating([](reporting::UploadClient::CreatedCallback
-                                       update_upload_client_cb) {
-              reporting::FakeUploadClient::Create(
-                  std::move(update_upload_client_cb));
-            })) {}
+            base::BindRepeating(&FakeUploadClient::Create)) {}
 };
 
 class EncryptedReportingUploadProviderTest : public ::testing::Test {
  public:
-  MOCK_METHOD(void,
-              ReportSuccessfulUpload,
-              (reporting::SequenceInformation, bool),
-              ());
-  MOCK_METHOD(void,
-              EncryptionKeyCallback,
-              (reporting::SignedEncryptionInfo),
-              ());
+  MOCK_METHOD(void, ReportSuccessfulUpload, (SequenceInformation, bool), ());
+  MOCK_METHOD(void, EncryptionKeyCallback, (SignedEncryptionInfo), ());
 
  protected:
   void SetUp() override {
@@ -99,7 +89,7 @@
     auto* sequence_information = record_.mutable_sequence_information();
     sequence_information->set_sequencing_id(42);
     sequence_information->set_generation_id(1701);
-    sequence_information->set_priority(reporting::Priority::SLOW_BATCH);
+    sequence_information->set_priority(Priority::SLOW_BATCH);
   }
 
   void TearDown() override {
@@ -122,7 +112,7 @@
 
   policy::MockCloudPolicyClient cloud_policy_client_;
   ReportingServerConnector::TestEnvironment test_env_{&cloud_policy_client_};
-  reporting::EncryptedRecord record_;
+  EncryptedRecord record_;
 
   scoped_refptr<ResourceInterface> memory_resource_;
 
diff --git a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc
index 006866f..e34fa12 100644
--- a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc
+++ b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context.cc
@@ -67,7 +67,7 @@
   CheckOnValidSequence();
   ReportQueueConfiguration::PolicyCheckCallback policy_check_cb =
       base::BindRepeating([]() -> Status { return Status::StatusOK(); });
-  auto config_result = reporting::ReportQueueConfiguration::Create(
+  auto config_result = ReportQueueConfiguration::Create(
       // using an empty DM token cause device DM tokens are appended by default
       // during event uploads
       /*dm_token=*/"", destination_, std::move(policy_check_cb));
@@ -85,9 +85,8 @@
     return;
   }
 
-  auto report_queue_result =
-      reporting::ReportQueueProvider::CreateSpeculativeQueue(
-          std::move(config_result.ValueOrDie()));
+  auto report_queue_result = ReportQueueProvider::CreateSpeculativeQueue(
+      std::move(config_result.ValueOrDie()));
   Schedule(&ReportQueueManualTestContext::OnReportQueueResponse,
            base::Unretained(this), std::move(report_queue_result));
 }
diff --git a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context_unittest.cc b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context_unittest.cc
index f9b9258..289d576 100644
--- a/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/util/report_queue_manual_test_context_unittest.cc
@@ -40,9 +40,8 @@
     task_runner_ =
         base::ThreadPool::CreateSequencedTaskRunner(base::TaskTraits());
     mock_report_queue_ =
-        std::unique_ptr<reporting::MockReportQueue, base::OnTaskRunnerDeleter>(
-            new reporting::MockReportQueue(),
-            base::OnTaskRunnerDeleter(task_runner_));
+        std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>(
+            new MockReportQueue(), base::OnTaskRunnerDeleter(task_runner_));
     auto build_report_queue_cb = base::BindOnce(
         &ReportQueueManualTestContextTest::BuildReportQueueCallback,
         base::Unretained(this));
@@ -63,11 +62,11 @@
     dm_token_ = std::move(report_queue_config)->dm_token();
   }
 
-  std::unique_ptr<reporting::MockReportQueue, base::OnTaskRunnerDeleter>
-      mock_report_queue_ = std::unique_ptr<reporting::MockReportQueue,
-                                           base::OnTaskRunnerDeleter>(
-          nullptr,
-          base::OnTaskRunnerDeleter(nullptr));
+  std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>
+      mock_report_queue_ =
+          std::unique_ptr<MockReportQueue, base::OnTaskRunnerDeleter>(
+              nullptr,
+              base::OnTaskRunnerDeleter(nullptr));
 
   std::string dm_token_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index ced0a588..0da1ffd 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -2024,8 +2024,13 @@
   base::RepeatingClosure quit_closure_;
 };
 
+#if BUILDFLAG(IS_CHROMEOS)
+#define MAYBE_LensRegionSearchWithValidRegionUnifiedSidePanel DISABLED_LensRegionSearchWithValidRegionUnifiedSidePanel
+#else
+#define MAYBE_LensRegionSearchWithValidRegionUnifiedSidePanel LensRegionSearchWithValidRegionUnifiedSidePanel
+#endif
 IN_PROC_BROWSER_TEST_F(SearchByRegionWithUnifiedSidePanelBrowserTest,
-                       LensRegionSearchWithValidRegionUnifiedSidePanel) {
+                       MAYBE_LensRegionSearchWithValidRegionUnifiedSidePanel) {
   lens::CreateLensUnifiedSidePanelEntryForTesting(browser());
   SetupAndLoadPage("/empty.html");
   // We need a base::RunLoop to ensure that our test does not finish until the
diff --git a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
index ea30107..3ac4cf6 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
+++ b/chrome/browser/resources/chromeos/login/screens/common/sync_consent.js
@@ -46,11 +46,6 @@
   static get properties() {
     return {
       /**
-       * Flag that determines whether current account type is supervised or not.
-       */
-      isChildAccount_: Boolean,
-
-      /**
        * Indicates whether user is minor mode user (e.g. under age of 18).
        * @private
        */
@@ -79,7 +74,6 @@
     super();
     this.UI_STEPS = SyncUIState;
 
-    this.isChildAccount_ = false;
     this.isMinorMode_ = false;
     this.isArcRestricted_ = false;
   }
@@ -98,7 +92,6 @@
    * @param {Object} data Screen init payload.
    */
   onBeforeShow(data) {
-    this.setIsChildAccount(data['isChildAccount']);
     this.isArcRestricted_ = data['isArcRestricted'];
   }
 
@@ -106,14 +99,6 @@
     return SyncUIState.LOADING;
   }
 
-  /**
-   * Set flag isChildAccount_ value.
-   * @param is_child_account Boolean
-   */
-  setIsChildAccount(is_child_account) {
-    this.isChildAccount_ = is_child_account;
-  }
-
   /** @override */
   ready() {
     super.ready();
diff --git a/chrome/browser/resources/new_tab_page/preprocess_if_expr_sourcemaps.gni b/chrome/browser/resources/new_tab_page/preprocess_if_expr_sourcemaps.gni
index bed81d76..0777c69 100644
--- a/chrome/browser/resources/new_tab_page/preprocess_if_expr_sourcemaps.gni
+++ b/chrome/browser/resources/new_tab_page/preprocess_if_expr_sourcemaps.gni
@@ -31,13 +31,20 @@
   }
 
   if (enable_webui_inline_sourcemaps) {
+    _in_folder = "."
+    if (defined(invoker.in_folder)) {
+      _in_folder = invoker.in_folder
+    }
+
     create_js_source_maps(target_name) {
       inline_sourcemaps = true
+      originals = []
       sources = []
       outputs = []
       foreach(in_file, invoker.in_files) {
         assert(get_path_info(in_file, "extension") == "ts" ||
                get_path_info(in_file, "extension") == "js")
+        originals += [ "$_in_folder/$in_file" ]
         sources += [ "$_preprocess_if_expr_out_folder/" + in_file ]
         outputs += [ "$_out_folder/" + in_file ]
       }
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_delete_confirmation_dialog.ts b/chrome/browser/resources/settings/search_engines_page/search_engine_delete_confirmation_dialog.ts
index 3eb8c19..95b514f6 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_delete_confirmation_dialog.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_delete_confirmation_dialog.ts
@@ -14,8 +14,6 @@
 import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {loadTimeData} from '../i18n_setup.js';
-
 import {getTemplate} from './search_engine_delete_confirmation_dialog.html.js';
 import {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl} from './search_engines_browser_proxy.js';
 
@@ -43,12 +41,6 @@
   static get properties() {
     return {
       model: Object,
-
-      isActiveSearchEnginesFlagEnabled_: {
-        type: Boolean,
-        value: () =>
-            loadTimeData.getBoolean('isActiveSearchEnginesFlagEnabled'),
-      },
     };
   }
 
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.html b/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.html
index 310251147..c32c4f0 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.html
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.html
@@ -10,7 +10,7 @@
             autofocus>
         </cr-input>
         <cr-input id="keyword"
-            label="[[keywordFieldLabel_]]"
+            label="$i18n{searchEnginesShortcut}"
             error-message="$i18n{notValid}"
             value="{{keyword_}}" on-focus="validate_" on-input="validate_">
         </cr-input>
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.ts b/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.ts
index 9391ec79..fdcf18b 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_edit_dialog.ts
@@ -64,14 +64,7 @@
       keyword_: String,
       queryUrl_: String,
       dialogTitle_: String,
-      keywordFieldLabel_: String,
       actionButtonText_: String,
-
-      isActiveSearchEnginesFlagEnabled_: {
-        type: Boolean,
-        value: () =>
-            loadTimeData.getBoolean('isActiveSearchEnginesFlagEnabled'),
-      },
     };
   }
 
@@ -80,11 +73,9 @@
   private keyword_: string;
   private queryUrl_: string;
   private dialogTitle_: string;
-  private keywordFieldLabel_: string;
   private actionButtonText_: string;
   private browserProxy_: SearchEnginesBrowserProxy =
       SearchEnginesBrowserProxyImpl.getInstance();
-  private isActiveSearchEnginesFlagEnabled_: boolean;
 
   override ready() {
     super.ready();
@@ -104,10 +95,6 @@
       this.actionButtonText_ = loadTimeData.getString('add');
     }
 
-    this.keywordFieldLabel_ = this.isActiveSearchEnginesFlagEnabled_ ?
-        loadTimeData.getString('searchEnginesShortcut') :
-        loadTimeData.getString('searchEnginesKeyword');
-
     this.addEventListener('cancel', () => {
       this.browserProxy_.searchEngineEditCancelled();
     });
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
index a79ddd1..f3bb982 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html
@@ -6,10 +6,6 @@
       #name-column {
         align-items: center;
         display: flex;
-      }
-
-      #name-column,
-      #keyword-column {
         flex: 3;
         word-break: break-word;
       }
@@ -19,14 +15,6 @@
         word-break: break-word;
       }
 
-      #keyword-column > div {
-        margin-inline-end: 8px;
-      }
-
-      #url-column {
-        flex: 4;
-      }
-
       #url-column-padded {
         flex: 3;
         margin-inline-end: 40px;
@@ -41,50 +29,33 @@
         </site-favicon>
         <div>[[engine.displayName]]</div>
       </span>
-      <span role="cell" id="keyword-column"
-          hidden="[[isActiveSearchEnginesFlagEnabled]]">
-        <div>[[engine.keyword]]</div>
-      </span>
       <span role="cell" id="shortcut-column" hidden="[[!showShortcut]]">
         <div>[[engine.keyword]]</div>
       </span>
-      <span role="cell" id="url-column" class="text-elide"
-          hidden="[[isActiveSearchEnginesFlagEnabled]]">
-        <div>[[engine.url]]</div>
-      </span>
       <span role="cell" id="url-column-padded" class="text-elide"
           hidden="[[!showQueryUrl]]">
         <div>[[engine.url]]</div>
       </span>
       <span role="cell">
-        <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled]]">
-          <cr-button class="secondary-button" on-click="onActivateTap_"
-              hidden="[[!engine.canBeActivated]]" id="activate">
-            $i18n{searchEnginesActivate}
-          </cr-button>
-          <cr-icon-button class="icon-edit" on-click="onEditTap_"
-              title="$i18n{edit}" hidden="[[engine.canBeActivated]]"
-              disabled$="[[!engine.canBeEdited]]" id="editIconButton">
-          </cr-icon-button>
-        </template>
+        <cr-button class="secondary-button" on-click="onActivateTap_"
+            hidden="[[!engine.canBeActivated]]" id="activate">
+          $i18n{searchEnginesActivate}
+        </cr-button>
+        <cr-icon-button class="icon-edit" on-click="onEditTap_"
+            title="$i18n{edit}" hidden="[[engine.canBeActivated]]"
+            disabled$="[[!engine.canBeEdited]]" id="editIconButton">
+        </cr-icon-button>
         <cr-icon-button class="icon-more-vert" on-click="onDotsTap_"
-            disabled$="[[disableMenuButton]]" title="$i18n{moreActions}">
+            disabled$="[[engine.isDefault]]" title="$i18n{moreActions}">
         </cr-icon-button>
         <cr-action-menu role-description="$i18n{menu}">
           <button class="dropdown-item" on-click="onMakeDefaultTap_"
               disabled$="[[!engine.canBeDefault]]" id="makeDefault">
             $i18n{searchEnginesMakeDefault}
           </button>
-          <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled]]">
-            <button class="dropdown-item" on-click="onDeactivateTap_"
-                hidden="[[!engine.canBeDeactivated]]" id="deactivate">
-              $i18n{searchEnginesDeactivate}
-            </button>
-          </template>
-          <button class="dropdown-item" on-click="onEditTap_"
-              hidden="[[isActiveSearchEnginesFlagEnabled]]"
-              disabled$="[[!engine.canBeEdited]]" id="edit">
-            $i18n{edit}
+          <button class="dropdown-item" on-click="onDeactivateTap_"
+              hidden="[[!engine.canBeDeactivated]]" id="deactivate">
+            $i18n{searchEnginesDeactivate}
           </button>
           <button class="dropdown-item" on-click="onDeleteTap_"
               hidden="[[!engine.canBeRemoved]]" id="delete">
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
index da525cf..28cc1c2 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_entry.ts
@@ -45,7 +45,6 @@
 
       showQueryUrl: {type: Boolean, value: false, reflectToAttribute: true},
 
-      isActiveSearchEnginesFlagEnabled: Boolean,
 
       isDefault: {
         reflectToAttribute: true,
@@ -53,21 +52,13 @@
         computed: 'computeIsDefault_(engine)',
       },
 
-      disableMenuButton: {
-        reflectToAttribute: true,
-        type: Boolean,
-        computed: 'computeDisableMenuButton_(engine)',
-      },
-
     };
   }
 
   engine: SearchEngine;
   showShortcut: boolean;
   showQueryUrl: boolean;
-  isActiveSearchEnginesFlagEnabled: boolean;
   isDefault: boolean;
-  disableMenuButton: boolean;
   private browserProxy_: SearchEnginesBrowserProxy =
       SearchEnginesBrowserProxyImpl.getInstance();
 
@@ -79,10 +70,6 @@
     return this.engine.default;
   }
 
-  private computeDisableMenuButton_(): boolean {
-    return this.isActiveSearchEnginesFlagEnabled && this.engine.default;
-  }
-
   private onDeleteTap_(e: Event) {
     e.preventDefault();
     this.closePopupMenu_();
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
index 2b8fc43..cab264e6 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
+++ b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
@@ -4,8 +4,7 @@
         padding: 10px 0;
       }
 
-      #headers .name,
-      #headers .keyword {
+      #headers .name {
         flex: 3;
       }
 
@@ -41,24 +40,15 @@
       <div role="rowgroup">
         <div role="row" id="headers" class="column-header">
           <span class="name" role="columnheader">[[nameColumnHeader]]</span>
-          <span class="keyword" role="columnheader"
-              hidden="[[isActiveSearchEnginesFlagEnabled]]">
-            $i18n{searchEnginesKeyword}
-          </span>
           <span class="shortcut" role="columnheader" hidden="[[!showShortcut]]">
             $i18n{searchEnginesShortcut}
           </span>
-          <span class="url" role="columnheader"
-              hidden="[[isActiveSearchEnginesFlagEnabled]]">
-            $i18n{searchEnginesQueryURL}
-          </span>
           <span class="url-padded" role="columnheader"
                 hidden="[[!showQueryUrl]]">
             $i18n{searchEnginesQueryURL}
           </span>
           <span class="icon-placeholder"></span>
-          <span class="icon-placeholder"
-               hidden="[[!isActiveSearchEnginesFlagEnabled]]"></span>
+          <span class="icon-placeholder"></span>
         </div>
       </div>
       <template is="dom-if" if="[[!collapseList]]">
@@ -68,8 +58,6 @@
             <dom-repeat items="[[engines]]">
               <template>
                 <settings-search-engine-entry engine="[[item]]"
-                    is-active-search-engines-flag-enabled=
-                          "[[isActiveSearchEnginesFlagEnabled]]"
                     show-query-url="[[showQueryUrl]]"
                     show-shortcut="[[showShortcut]]">
                 </settings-search-engine-entry>
@@ -87,8 +75,6 @@
             <dom-repeat items="[[visibleEngines]]">
               <template>
                 <settings-search-engine-entry engine="[[item]]"
-                    is-active-search-engines-flag-enabled=
-                          "[[isActiveSearchEnginesFlagEnabled]]"
                     show-shortcut="[[showShortcut]]"
                     show-query-url="[[showQueryUrl]]">
                 </settings-search-engine-entry>
@@ -106,8 +92,6 @@
               <dom-repeat items="[[collapsedEngines]]">
                 <template>
                   <settings-search-engine-entry engine="[[item]]"
-                      is-active-search-engines-flag-enabled=
-                            "[[isActiveSearchEnginesFlagEnabled]]"
                       show-shortcut="[[showShortcut]]"
                       show-query-url="[[showQueryUrl]]">
                   </settings-search-engine-entry>
@@ -117,4 +101,4 @@
           </iron-collapse>
         </div>
       </template>
-    </div>
\ No newline at end of file
+    </div>
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_list.ts b/chrome/browser/resources/settings/search_engines_page/search_engines_list.ts
index 3c72013..c763de1 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engines_list.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engines_list.ts
@@ -29,11 +29,6 @@
     return {
       engines: Array,
 
-      /**
-       * Whether the active search engines feature flag is enabled.
-       */
-      isActiveSearchEnginesFlagEnabled: Boolean,
-
       showShortcut: {
         type: Boolean,
         value: false,
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
index 2f304db..f8e2c870 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
+++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.html
@@ -3,10 +3,8 @@
         border-top: var(--cr-separator-line);
       }
     </style>
-    <div class="cr-row first" hidden="[[!isActiveSearchEnginesFlagEnabled_]]">
-      <div class="secondary">
-          $i18n{searchEnginesPageExplanation}
-      </div>
+    <div class="cr-row first">
+      <div class="secondary">$i18n{searchEnginesPageExplanation}</div>
     </div>
     <div class="cr-row first">
       <div class="flex cr-padded-text">
@@ -37,35 +35,18 @@
       </settings-radio-group>
     </div>
 
-    <template is="dom-if" if="[[!isActiveSearchEnginesFlagEnabled_]]">
-      <div class="cr-row first">
-        <h2>$i18n{searchEnginesDefault}</h2>
-      </div>
-      <settings-search-engines-list fixed-height
-          hidden="[[!matchingDefaultEngines_.length]]"
-          engines="[[matchingDefaultEngines_]]"
-          is-active-search-engines-flag-enabled=
-            "[[isActiveSearchEnginesFlagEnabled_]]"
-          name-column-header="$i18n{searchEnginesSearchEngine}">
-      </settings-search-engines-list>
-    </template>
-    <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled_]]">
-      <div class="cr-row first">
-        <div class="flex cr-padded-text">
-          <h2>$i18n{searchEnginesSearchEngines}</h2>
-          <div class="secondary">
-            $i18n{searchEnginesSearchEnginesExplanation}
-          </div>
+    <div class="cr-row first">
+      <div class="flex cr-padded-text">
+        <h2>$i18n{searchEnginesSearchEngines}</h2>
+        <div class="secondary">
+          $i18n{searchEnginesSearchEnginesExplanation}
         </div>
       </div>
-      <settings-search-engines-list
-          hidden="[[!matchingDefaultEngines_.length]]"
-          engines="[[matchingDefaultEngines_]]"
-          is-active-search-engines-flag-enabled=
-                  "[[isActiveSearchEnginesFlagEnabled_"]] show-shortcut
-          name-column-header="$i18n{searchEnginesSearchEngine}">
-      </settings-search-engines-list>
-    </template>
+    </div>
+    <settings-search-engines-list hidden="[[!matchingDefaultEngines_.length]]"
+        engines="[[matchingDefaultEngines_]]"
+        show-shortcut name-column-header="$i18n{searchEnginesSearchEngine}">
+    </settings-search-engines-list>
 
     <div class="no-search-results list-frame"
         hidden="[[matchingDefaultEngines_.length]]">
@@ -84,8 +65,7 @@
       </settings-search-engine-delete-confirmation-dialog>
     </template>
 
-    <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled_]]">
-      <div class="cr-row first">
+    <div class="cr-row first">
         <div class="flex cr-padded-text">
           <h2>$i18n{searchEnginesSiteSearch}</h2>
           <div class="secondary">$i18n{searchEnginesSiteSearchExplanation}</div>
@@ -94,61 +74,37 @@
                    on-click="onAddSearchEngineTap_" id="addSearchEngine">
           $i18n{add}
         </cr-button>
-      </div>
-      <div id="noActiveEngines" class="list-frame"
+    </div>
+    <div id="noActiveEngines" class="list-frame"
            hidden="[[activeEngines.length]]">
           $i18n{searchEnginesNoSitesAdded}
-      </div>
-      <div class="no-search-results list-frame"
+    </div>
+    <div class="no-search-results list-frame"
            hidden="[[!showNoResultsMessage_(
           activeEngines, matchingActiveEngines_)]]">
           $i18n{searchNoResults}
-      </div>
-      <settings-search-engines-list id="activeEngines"
-          hidden="[[!matchingActiveEngines_.length]]"
-          engines="[[matchingActiveEngines_]]"
-          scroll-target="[[subpageScrollTarget]]"
-          is-active-search-engines-flag-enabled=
-                "[[isActiveSearchEnginesFlagEnabled_]]"
-          show-shortcut collapse-list
-          expand-list-text="$i18n{searchEnginesAdditionalSites}"
-          name-column-header="$i18n{searchEnginesSiteOrPage}">
-      </settings-search-engines-list>
-    </template>
+    </div>
+    <settings-search-engines-list id="activeEngines"
+        hidden="[[!matchingActiveEngines_.length]]"
+        engines="[[matchingActiveEngines_]]"
+        scroll-target="[[subpageScrollTarget]]"
+        show-shortcut collapse-list
+        expand-list-text="$i18n{searchEnginesAdditionalSites}"
+        name-column-header="$i18n{searchEnginesSiteOrPage}">
+    </settings-search-engines-list>
 
-    <template is="dom-if" if="[[!isActiveSearchEnginesFlagEnabled_]]">
-      <div class="cr-row first">
-        <h2 class="flex">$i18n{searchEnginesOther}</h2>
-        <cr-button class="secondary-button header-aligned-button"
-                   on-click="onAddSearchEngineTap_" id="addSearchEngine">
-          $i18n{add}
-        </cr-button>
-      </div>
-      <settings-search-engines-list id="otherEngines"
-          hidden="[[!matchingOtherEngines_.length]]"
-          engines="[[matchingOtherEngines_]]"
-          scroll-target="[[subpageScrollTarget]]"
-          is-active-search-engines-flag-enabled=
-                "[[isActiveSearchEnginesFlagEnabled_]]"
-          name-column-header="$i18n{searchEnginesSearchEngine}">
-      </settings-search-engines-list>
-    </template>
-
-    <template is="dom-if" if="[[isActiveSearchEnginesFlagEnabled_]]">
-      <div class="cr-row first">
+    <div class="cr-row first">
         <h2>$i18n{searchEnginesInactiveShortcuts}</h2>
-      </div>
-      <settings-search-engines-list
-          hidden="[[!matchingOtherEngines_.length]]"
-          engines="[[matchingOtherEngines_]]"
-          scroll-target="[[subpageScrollTarget]]"
-          is-active-search-engines-flag-enabled=
-                "[[isActiveSearchEnginesFlagEnabled_]]"
-          show-query-url collapse-list
-          expand-list-text="$i18n{searchEnginesAdditionalInactiveSites}"
-          name-column-header="$i18n{searchEnginesSiteOrPage}">
-      </settings-search-engines-list>
-    </template>
+    </div>
+    <settings-search-engines-list
+        hidden="[[!matchingOtherEngines_.length]]"
+        engines="[[matchingOtherEngines_]]"
+        scroll-target="[[subpageScrollTarget]]"
+        show-query-url collapse-list
+        expand-list-text="$i18n{searchEnginesAdditionalInactiveSites}"
+        name-column-header="$i18n{searchEnginesSiteOrPage}">
+    </settings-search-engines-list>
+
     <div id="noOtherEngines" class="list-frame"
         hidden="[[otherEngines.length]]">
       $i18n{searchEnginesNoOtherEngines}
@@ -163,10 +119,7 @@
       <div class="cr-row first">
         <div class="flex cr-padded-text">
           <h2 class="flex">$i18n{searchEnginesExtension}</h2>
-          <div class="secondary"
-               hidden="[[!isActiveSearchEnginesFlagEnabled_]]">
-            $i18n{searchEnginesExtensionExplanation}
-          </div>
+          <div class="secondary"> $i18n{searchEnginesExtensionExplanation}</div>
         </div>
       </div>
       <div class="no-search-results list-frame"
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts b/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts
index be19d9b..f1362e1 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts
+++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts
@@ -27,7 +27,6 @@
 
 import {SettingsRadioGroupElement} from '../controls/settings_radio_group.js';
 import {GlobalScrollTargetMixin} from '../global_scroll_target_mixin.js';
-import {loadTimeData} from '../i18n_setup.js';
 import {routes} from '../route.js';
 
 import {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl, SearchEnginesInfo, SearchEnginesInteractions} from './search_engines_browser_proxy.js';
@@ -140,12 +139,6 @@
         type: Boolean,
         value: false,
       },
-
-      isActiveSearchEnginesFlagEnabled_: {
-        type: Boolean,
-        value: () =>
-            loadTimeData.getBoolean('isActiveSearchEnginesFlagEnabled'),
-      },
     };
   }
 
@@ -169,7 +162,6 @@
   private dialogAnchorElement_: HTMLElement|null;
   private showEditDialog_: boolean;
   private showDeleteConfirmationDialog_: boolean;
-  private isActiveSearchEnginesFlagEnabled_: boolean;
   private browserProxy_: SearchEnginesBrowserProxy =
       SearchEnginesBrowserProxyImpl.getInstance();
 
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html
index fde665e..69b502d 100644
--- a/chrome/browser/resources/settings/search_page/search_page.html
+++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -50,14 +50,14 @@
 
     <!-- Manage search engines -->
     <cr-link-row class="hr" id="enginesSubpageTrigger"
-        label="[[searchEnginesPageTitle_]]"
+        label="$i18n{searchEnginesManageSiteSearch}"
         on-click="onManageSearchEnginesTap_"
         role-description="$i18n{subpageArrowRoleDescription}"></cr-link-row>
   </div>
   <template is="dom-if" route-path="/searchEngines">
     <settings-subpage
         associated-control="[[$$('#enginesSubpageTrigger')]]"
-        page-title="[[searchEnginesPageTitle_]]"
+        page-title="$i18n{searchEnginesManageSiteSearch}"
         search-label="$i18n{searchEnginesSearch}"
         search-term="{{searchEnginesFilter_}}">
       <settings-search-engines-page prefs="{{prefs}}"
diff --git a/chrome/browser/resources/settings/search_page/search_page.ts b/chrome/browser/resources/settings/search_page/search_page.ts
index 0ab8f983..dc06329 100644
--- a/chrome/browser/resources/settings/search_page/search_page.ts
+++ b/chrome/browser/resources/settings/search_page/search_page.ts
@@ -19,18 +19,16 @@
 import '../settings_vars.css.js';
 
 import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
-import {I18nMixin} from 'chrome://resources/js/i18n_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {BaseMixin} from '../base_mixin.js';
-import {loadTimeData} from '../i18n_setup.js';
 import {routes} from '../route.js';
 import {Router} from '../router.js';
 import {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl, SearchEnginesInfo} from '../search_engines_page/search_engines_browser_proxy.js';
 
 import {getTemplate} from './search_page.html.js';
 
-const SettingsSearchPageElementBase = BaseMixin(I18nMixin(PolymerElement));
+const SettingsSearchPageElementBase = BaseMixin(PolymerElement);
 
 export class SettingsSearchPageElement extends SettingsSearchPageElementBase {
   static get is() {
@@ -60,22 +58,10 @@
 
       focusConfig_: Object,
 
-      isActiveSearchEnginesFlagEnabled_: {
-        type: Boolean,
-        value: () =>
-            loadTimeData.getBoolean('isActiveSearchEnginesFlagEnabled'),
-      },
-
-      searchEnginesPageTitle_: {
-        type: String,
-        computed: 'computeSearchEnginesPageTitle_()',
-      },
     };
   }
 
   prefs: Object;
-  private searchEnginesPageTitle_: string;
-  private isActiveSearchEnginesFlagEnabled_: boolean;
   private searchEngines_: SearchEngine[];
   private searchEnginesFilter_: string;
   private focusConfig_: Map<string, string>|null;
@@ -127,12 +113,6 @@
       pref: chrome.settingsPrivate.PrefObject): boolean {
     return pref.enforcement === chrome.settingsPrivate.Enforcement.ENFORCED;
   }
-
-  private computeSearchEnginesPageTitle_(): string {
-    return this.isActiveSearchEnginesFlagEnabled_ ?
-        this.i18n('searchEnginesManageSiteSearch') :
-        this.i18n('searchEnginesManage');
-  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/webapks/about_webapks.ts b/chrome/browser/resources/webapks/about_webapks.ts
index c946998..e5ed0ad 100644
--- a/chrome/browser/resources/webapks/about_webapks.ts
+++ b/chrome/browser/resources/webapks/about_webapks.ts
@@ -16,6 +16,7 @@
   scope: string;
   manifestUrl: string;
   manifestStartUrl: string;
+  manifestId: string;
   displayMode: string;
   orientation: string;
   themeColor: string;
@@ -98,6 +99,7 @@
   addWebApkField(webApkList, 'Manifest URL: ', webApkInfo.manifestUrl);
   addWebApkField(
       webApkList, 'Manifest Start URL: ', webApkInfo.manifestStartUrl);
+  addWebApkField(webApkList, 'Manifest Id: ', webApkInfo.manifestId);
   addWebApkField(webApkList, 'Display Mode: ', webApkInfo.displayMode);
   addWebApkField(webApkList, 'Orientation: ', webApkInfo.orientation);
   addWebApkField(webApkList, 'Theme color: ', webApkInfo.themeColor);
diff --git a/chrome/browser/resources/webui_gallery/BUILD.gn b/chrome/browser/resources/webui_gallery/BUILD.gn
index 4371a67..8f3cbfe 100644
--- a/chrome/browser/resources/webui_gallery/BUILD.gn
+++ b/chrome/browser/resources/webui_gallery/BUILD.gn
@@ -2,14 +2,64 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//chrome/browser/resources/tools/build_webui.gni")
+import("//tools/grit/grit_rule.gni")
+import("//tools/polymer/html_to_wrapper.gni")
+import("//tools/typescript/ts_library.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
+import("webui_gallery.gni")
 
 assert(!is_android)
 
-build_webui("build") {
-  grd_prefix = "webui_gallery"
+grit("resources") {
+  # These arguments are needed since the grd is generated at build time.
+  enable_input_discovery_for_gn_analyze = false
+  source = "$target_gen_dir/resources.grd"
+  deps = [ ":build_grd" ]
 
-  static_files = [
+  outputs = [
+    "grit/webui_gallery_resources.h",
+    "grit/webui_gallery_resources_map.cc",
+    "grit/webui_gallery_resources_map.h",
+    "webui_gallery_resources.pak",
+  ]
+  output_dir = "$root_gen_dir/chrome"
+}
+
+html_to_wrapper("html_wrapper_files") {
+  in_files = html_files
+}
+
+html_to_wrapper("html_wrapper_files_native") {
+  in_files = html_files_native
+  template = "native"
+}
+
+copy("copy_ts_files") {
+  sources = ts_files
+  outputs = [ "$target_gen_dir/{{source_target_relative}}" ]
+}
+
+ts_library("build_ts") {
+  root_dir = target_gen_dir
+  out_dir = "$target_gen_dir/tsc"
+  tsconfig_base = "tsconfig_base.json"
+  in_files = ts_files + html_wrapper_files + html_wrapper_files_native
+  deps = [
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources:library",
+  ]
+  extra_deps = [
+    ":copy_ts_files",
+    ":html_wrapper_files",
+    ":html_wrapper_files_native",
+  ]
+}
+
+generate_grd("build_grd") {
+  grd_prefix = "webui_gallery"
+  out_grd = "$target_gen_dir/resources.grd"
+
+  input_files = [
     "demos/demo.css",
     "demos/cr_a11y_announcer_demo.html",
     "demos/cr_action_menu_demo.html",
@@ -19,22 +69,13 @@
     "demos/cr_input/cr_input_demo.html",
     "demos/cr_radio_demo.html",
     "demos/cr_slider/cr_slider_demo.html",
+    "demos/cr_tab_box/cr_tab_box_demo.html",
     "demos/cr_toggle_demo.html",
     "webui_gallery.html",
   ]
 
-  # Files holding a Polymer element definition AND have an equivalent .html file.
-  web_component_files = [
-    "app.ts",
-    "demos/cr_a11y_announcer_demo_component.ts",
-    "demos/cr_action_menu_demo_component.ts",
-    "demos/cr_dialog_demo_component.ts",
-    "demos/cr_input/cr_input_demo_component.ts",
-    "demos/cr_slider/cr_slider_demo_component.ts",
-  ]
-
-  ts_deps = [
-    "//third_party/polymer/v3_0:library",
-    "//ui/webui/resources:library",
-  ]
+  input_files_base_dir = rebase_path(".", "//")
+  deps = [ ":build_ts" ]
+  manifest_files =
+      filter_include(get_target_outputs(":build_ts"), [ "*.manifest" ])
 }
diff --git a/chrome/browser/resources/webui_gallery/app.ts b/chrome/browser/resources/webui_gallery/app.ts
index da52ee4b..d85b8bc 100644
--- a/chrome/browser/resources/webui_gallery/app.ts
+++ b/chrome/browser/resources/webui_gallery/app.ts
@@ -75,6 +75,11 @@
               src: 'cr_slider/cr_slider_demo.html',
             },
             {
+              name: 'Tabs, non Polymer',
+              path: 'tabs1',
+              src: 'cr_tab_box/cr_tab_box_demo.html',
+            },
+            {
               name: 'Toggles',
               path: 'toggles',
               src: 'cr_toggle_demo.html',
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html
new file mode 100644
index 0000000..62f7333
--- /dev/null
+++ b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>cr-tab-box demo</title>
+    <link rel="stylesheet" href="demo.css">
+  </head>
+  <body>
+    <cr-tab-box-demo></cr-tab-box-demo>
+    <script src="cr_tab_box_demo_component.js" type="module"></script>
+  </body>
+</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.html b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.html
new file mode 100644
index 0000000..f019f2c
--- /dev/null
+++ b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.html
@@ -0,0 +1,56 @@
+<link rel="stylesheet" href="../demo.css">
+<style>
+  div[slot='panel'] {
+    padding: 90px 0;
+    width: 100%;
+  }
+
+  button {
+    background: white;
+    border: 1px solid #c8c8c8;
+    color: #646464;
+    line-height: 24px;
+    margin-inline-end: 10px;
+  }
+
+  button:hover {
+    color: black;
+  }
+
+  button:active {
+    box-shadow: 0 1px 2px 0 rgba(200, 200, 200, .3),
+        0 3px 6px 2px rgba(200, 200, 200, .15);
+    color: black;
+  }
+
+  span {
+    font-family: sans-serif;
+    font-size: 10pt;
+  }
+</style>
+<h1>cr-tab-box</h1>
+<div class="demos">
+  <cr-tab-box>
+    <div slot="tab">Tab 1</div>
+    <div slot="tab">Tab 2</div>
+    <div slot="tab">Tab 3</div>
+    <div slot="panel">Tab 1</div>
+    <div slot="panel">Tab 2</div>
+    <div slot="panel">Tab 3</div>
+  </cr-tab-box>
+  <div class="buttons">
+    <button class="add-tab">Add</button>
+    <button class="add-tab-one">Add At 1</button>
+    <button class="select-tab-one">Select At 1</button>
+  </div>
+  <div class="info">
+    <span>Tab Count: </span>
+    <span class="tab-count"></span>
+    <span>, Selected Tab: </span>
+    <span class="selected-tab">0</span>
+  </div>
+</div>
+<template id="template">
+  <div slot="tab"></div>
+  <div slot="panel"></div>
+</template>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.ts b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.ts
new file mode 100644
index 0000000..7ebe7c0
--- /dev/null
+++ b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo_component.ts
@@ -0,0 +1,94 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_tab_box/cr_tab_box.js';
+
+import {CrTabBoxElement} from 'chrome://resources/cr_elements/cr_tab_box/cr_tab_box.js';
+import {assert} from 'chrome://resources/js/assert_ts.js';
+import {CustomElement} from 'chrome://resources/js/custom_element.js';
+
+import {getTemplate} from './cr_tab_box_demo_component.html.js';
+
+class CrTabBoxDemoComponent extends CustomElement {
+  static override get template() {
+    return getTemplate();
+  }
+
+  private tabBox_: CrTabBoxElement|null;
+
+  async connectedCallback() {
+    this.tabBox_ = this.shadowRoot!.querySelector('cr-tab-box');
+    assert(this.tabBox_);
+    this.tabBox_.addEventListener(
+        'selected-index-change', this.onSelectedIndexChange_.bind(this));
+
+    const selectButton = this.shadowRoot!.querySelector('.select-tab-one');
+    assert(selectButton);
+    selectButton.addEventListener('click', this.selectTabOne_.bind(this));
+
+    const addTabButton = this.shadowRoot!.querySelector('.add-tab');
+    assert(addTabButton);
+    addTabButton.addEventListener('click', () => this.addTabAt_(-1));
+
+    const addTabAtOneButton = this.shadowRoot!.querySelector('.add-tab-one');
+    assert(addTabAtOneButton);
+    addTabAtOneButton.addEventListener('click', () => this.addTabAt_(1));
+
+    this.updateTabCount_();
+  }
+
+  private onSelectedIndexChange_(e: CustomEvent<number>) {
+    this.shadowRoot!.querySelector<HTMLElement>('.selected-tab')!.textContent =
+        e.detail.toString();
+  }
+
+  private selectTabOne_() {
+    assert(this.tabBox_);
+    this.tabBox_.setAttribute('selected-index', '1');
+  }
+
+  private addTabAt_(index: number) {
+    const template =
+        this.shadowRoot!.querySelector<HTMLTemplateElement>('#template');
+    assert(template);
+    const clone =
+        document.importNode(template.content, true) as DocumentFragment;
+
+    const tab = clone.querySelector<HTMLElement>('div[slot=\'tab\']');
+    assert(tab);
+    const text = index === -1 ? 'Added' : `Added at ${index}`;
+    tab.textContent = text;
+    assert(this.tabBox_);
+
+    if (index === -1) {
+      const firstPanel = this.tabBox_.querySelector('div[slot=\'panel\']');
+      this.tabBox_.insertBefore(tab, firstPanel);
+    } else {
+      const tabs = this.tabBox_.querySelectorAll('div[slot=\'tab\']');
+      assert(index < tabs.length);
+      this.tabBox_.insertBefore(tab, tabs[index]!);
+    }
+
+    const panel = clone.querySelector<HTMLElement>('div[slot=\'panel\']');
+    assert(panel);
+    panel.textContent = text;
+
+    if (index === -1) {
+      this.tabBox_.appendChild(panel);
+    } else {
+      const panels = this.tabBox_.querySelectorAll('div[slot=\'panel\']');
+      this.tabBox_.insertBefore(panel, panels[index]!);
+    }
+    this.updateTabCount_();
+  }
+
+  private updateTabCount_() {
+    assert(this.tabBox_);
+    const tabs = this.tabBox_.querySelectorAll('div[slot=\'tab\']');
+    this.shadowRoot!.querySelector<HTMLElement>('.tab-count')!.textContent =
+        tabs.length.toString();
+  }
+}
+
+customElements.define('cr-tab-box-demo', CrTabBoxDemoComponent);
diff --git a/chrome/browser/resources/webui_gallery/webui_gallery.gni b/chrome/browser/resources/webui_gallery/webui_gallery.gni
new file mode 100644
index 0000000..492add86
--- /dev/null
+++ b/chrome/browser/resources/webui_gallery/webui_gallery.gni
@@ -0,0 +1,41 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Files holding a Polymer element definition AND have an equivalent .html file.
+web_component_files = [
+  "app.ts",
+  "demos/cr_a11y_announcer_demo_component.ts",
+  "demos/cr_action_menu_demo_component.ts",
+  "demos/cr_dialog_demo_component.ts",
+  "demos/cr_input/cr_input_demo_component.ts",
+  "demos/cr_slider/cr_slider_demo_component.ts",
+]
+
+web_component_files_native = [ "demos/cr_tab_box/cr_tab_box_demo_component.ts" ]
+
+# Files that are passed as input to html_to_wrapper().
+html_files = []
+foreach(f, web_component_files) {
+  html_files += [ string_replace(f, ".ts", ".html") ]
+}
+
+# Files that are generated by html_to_wrapper().
+html_wrapper_files = []
+foreach(f, html_files) {
+  html_wrapper_files += [ f + ".ts" ]
+}
+
+# Files that are passed as input to html_to_wrapper().
+html_files_native = []
+foreach(f, web_component_files_native) {
+  html_files_native += [ string_replace(f, ".ts", ".html") ]
+}
+
+# Files that are generated by html_to_wrapper().
+html_wrapper_files_native = []
+foreach(f, html_files_native) {
+  html_wrapper_files_native += [ f + ".ts" ]
+}
+
+ts_files = web_component_files + web_component_files_native
diff --git a/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
index 7bb620d..afbf024 100644
--- a/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
@@ -116,10 +116,12 @@
   }
 
   void OnNewSettingsAvailable(const base::DictionaryValue* settings) {
-    if (!settings)
+    if (!settings) {
       settings_.reset();
-    else
-      settings_.reset(settings->DeepCopy());
+    } else {
+      settings_ = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(settings->Clone()));
+    }
   }
 
   // Check that a single website approval has been added correctly.
diff --git a/chrome/browser/ui/android/overlay/overlay_window_android.cc b/chrome/browser/ui/android/overlay/overlay_window_android.cc
index 8d580cb..534059d73a 100644
--- a/chrome/browser/ui/android/overlay/overlay_window_android.cc
+++ b/chrome/browser/ui/android/overlay/overlay_window_android.cc
@@ -36,6 +36,7 @@
       compositor_view_(nullptr),
       surface_layer_(cc::SurfaceLayer::Create()),
       bounds_(gfx::Rect(0, 0)),
+      update_action_timer_(std::make_unique<base::OneShotTimer>()),
       controller_(controller) {
   surface_layer_->SetIsDrawable(true);
   surface_layer_->SetStretchContentToFillBounds(true);
@@ -93,7 +94,13 @@
 
   Java_PictureInPictureActivity_setPlaybackState(env, java_ref_.get(env),
                                                  playback_state_);
-  MaybeNotifyVisibleActionsChanged();
+  Java_PictureInPictureActivity_setMicrophoneMuted(env, java_ref_.get(env),
+                                                   microphone_muted_);
+  Java_PictureInPictureActivity_setCameraState(env, java_ref_.get(env),
+                                               camera_on_);
+
+  if (!update_action_timer_->IsRunning())
+    MaybeNotifyVisibleActionsChanged();
 
   if (video_size_.IsEmpty())
     return;
@@ -124,7 +131,11 @@
     window_android_ = nullptr;
   }
 
-  controller_->OnWindowDestroyed(/*should_pause_video=*/true);
+  // Only pause the video when play/pause button is visible.
+  controller_->OnWindowDestroyed(
+      /*should_pause_video=*/visible_actions_.find(
+          static_cast<int>(media_session::mojom::MediaSessionAction::kPlay)) !=
+      visible_actions_.end());
 }
 
 void OverlayWindowAndroid::TogglePlayPause(JNIEnv* env) {
@@ -140,6 +151,18 @@
   controller_->PreviousTrack();
 }
 
+void OverlayWindowAndroid::ToggleMicrophone(JNIEnv* env) {
+  controller_->ToggleMicrophone();
+}
+
+void OverlayWindowAndroid::ToggleCamera(JNIEnv* env) {
+  controller_->ToggleCamera();
+}
+
+void OverlayWindowAndroid::HangUp(JNIEnv* env) {
+  controller_->HangUp();
+}
+
 void OverlayWindowAndroid::CompositorViewCreated(
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& compositor_view) {
@@ -229,30 +252,61 @@
                                                  playback_state);
 }
 
-void OverlayWindowAndroid::SetPlayPauseButtonVisibility(bool is_visible) {
-  if (!MaybeUpdateVisibleAction(media_session::mojom::MediaSessionAction::kPlay,
-                                is_visible)) {
+void OverlayWindowAndroid::SetMicrophoneMuted(bool muted) {
+  if (microphone_muted_ == muted)
     return;
-  }
 
-  MaybeUpdateVisibleAction(media_session::mojom::MediaSessionAction::kPause,
+  microphone_muted_ = muted;
+  if (java_ref_.is_uninitialized())
+    return;
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_PictureInPictureActivity_setMicrophoneMuted(env, java_ref_.get(env),
+                                                   microphone_muted_);
+}
+
+void OverlayWindowAndroid::SetCameraState(bool turned_on) {
+  if (camera_on_ == turned_on)
+    return;
+
+  camera_on_ = turned_on;
+  if (java_ref_.is_uninitialized())
+    return;
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_PictureInPictureActivity_setCameraState(env, java_ref_.get(env),
+                                               camera_on_);
+}
+
+void OverlayWindowAndroid::SetPlayPauseButtonVisibility(bool is_visible) {
+  MaybeUpdateVisibleAction(media_session::mojom::MediaSessionAction::kPlay,
                            is_visible);
-  MaybeNotifyVisibleActionsChanged();
 }
 
 void OverlayWindowAndroid::SetNextTrackButtonVisibility(bool is_visible) {
-  if (MaybeUpdateVisibleAction(
-          media_session::mojom::MediaSessionAction::kNextTrack, is_visible)) {
-    MaybeNotifyVisibleActionsChanged();
-  }
+  MaybeUpdateVisibleAction(media_session::mojom::MediaSessionAction::kNextTrack,
+                           is_visible);
 }
 
 void OverlayWindowAndroid::SetPreviousTrackButtonVisibility(bool is_visible) {
-  if (MaybeUpdateVisibleAction(
-          media_session::mojom::MediaSessionAction::kPreviousTrack,
-          is_visible)) {
-    MaybeNotifyVisibleActionsChanged();
-  }
+  MaybeUpdateVisibleAction(
+      media_session::mojom::MediaSessionAction::kPreviousTrack, is_visible);
+}
+
+void OverlayWindowAndroid::SetToggleMicrophoneButtonVisibility(
+    bool is_visible) {
+  MaybeUpdateVisibleAction(
+      media_session::mojom::MediaSessionAction::kToggleMicrophone, is_visible);
+}
+
+void OverlayWindowAndroid::SetToggleCameraButtonVisibility(bool is_visible) {
+  MaybeUpdateVisibleAction(
+      media_session::mojom::MediaSessionAction::kToggleCamera, is_visible);
+}
+
+void OverlayWindowAndroid::SetHangUpButtonVisibility(bool is_visible) {
+  MaybeUpdateVisibleAction(media_session::mojom::MediaSessionAction::kHangUp,
+                           is_visible);
 }
 
 void OverlayWindowAndroid::SetSurfaceId(const viz::SurfaceId& surface_id) {
@@ -289,13 +343,13 @@
           std::vector<int>(visible_actions_.begin(), visible_actions_.end())));
 }
 
-bool OverlayWindowAndroid::MaybeUpdateVisibleAction(
+void OverlayWindowAndroid::MaybeUpdateVisibleAction(
     const media_session::mojom::MediaSessionAction& action,
     bool is_visible) {
   int action_code = static_cast<int>(action);
   if ((visible_actions_.find(action_code) != visible_actions_.end()) ==
       is_visible) {
-    return false;
+    return;
   }
 
   if (is_visible)
@@ -303,5 +357,10 @@
   else
     visible_actions_.erase(action_code);
 
-  return true;
+  if (!update_action_timer_->IsRunning()) {
+    update_action_timer_->Start(
+        FROM_HERE, base::Seconds(1),
+        base::BindOnce(&OverlayWindowAndroid::MaybeNotifyVisibleActionsChanged,
+                       base::Unretained(this)));
+  }
 }
diff --git a/chrome/browser/ui/android/overlay/overlay_window_android.h b/chrome/browser/ui/android/overlay/overlay_window_android.h
index b655bad..b1daeb1 100644
--- a/chrome/browser/ui/android/overlay/overlay_window_android.h
+++ b/chrome/browser/ui/android/overlay/overlay_window_android.h
@@ -8,6 +8,7 @@
 #include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/memory/raw_ptr.h"
+#include "base/timer/timer.h"
 #include "content/public/browser/overlay_window.h"
 #include "third_party/blink/public/mojom/mediasession/media_session.mojom.h"
 #include "ui/android/window_android.h"
@@ -39,6 +40,9 @@
   void TogglePlayPause(JNIEnv* env);
   void NextTrack(JNIEnv* env);
   void PreviousTrack(JNIEnv* env);
+  void ToggleMicrophone(JNIEnv* env);
+  void ToggleCamera(JNIEnv* env);
+  void HangUp(JNIEnv* env);
   void CompositorViewCreated(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& compositor_view);
@@ -70,12 +74,11 @@
   void SetSkipAdButtonVisibility(bool is_visible) override {}
   void SetNextTrackButtonVisibility(bool is_visible) override;
   void SetPreviousTrackButtonVisibility(bool is_visible) override;
-  // TODO(crbug.com/1331269): Implement video conferencing actions.
-  void SetMicrophoneMuted(bool muted) override {}
-  void SetCameraState(bool turned_on) override {}
-  void SetToggleMicrophoneButtonVisibility(bool is_visible) override {}
-  void SetToggleCameraButtonVisibility(bool is_visible) override {}
-  void SetHangUpButtonVisibility(bool is_visible) override {}
+  void SetMicrophoneMuted(bool muted) override;
+  void SetCameraState(bool turned_on) override;
+  void SetToggleMicrophoneButtonVisibility(bool is_visible) override;
+  void SetToggleCameraButtonVisibility(bool is_visible) override;
+  void SetHangUpButtonVisibility(bool is_visible) override;
   void SetSurfaceId(const viz::SurfaceId& surface_id) override;
   cc::Layer* GetLayerForTesting() override;
 
@@ -84,7 +87,7 @@
   void MaybeNotifyVisibleActionsChanged();
 
   // Maybe update visible actions. Returns true if update happened.
-  bool MaybeUpdateVisibleAction(
+  void MaybeUpdateVisibleAction(
       const media_session::mojom::MediaSessionAction& action,
       bool is_visible);
   void CloseInternal();
@@ -100,6 +103,11 @@
   PlaybackState playback_state_ = PlaybackState::kEndOfVideo;
   std::unordered_set<int> visible_actions_;
 
+  bool microphone_muted_ = false;
+  bool camera_on_ = false;
+
+  std::unique_ptr<base::OneShotTimer> update_action_timer_;
+
   raw_ptr<content::VideoPictureInPictureWindowController> controller_;
 };
 
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
index c640f45..0e01ce4 100644
--- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
+++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.cc
@@ -201,6 +201,9 @@
     new_results.push_back(std::move(result));
   }
 
+  if (app_list_features::IsForceShowContinueSectionEnabled())
+    AppendFakeSearchResults(&new_results);
+
   UMA_HISTOGRAM_TIMES("Apps.AppList.ZeroStateFileProvider.Latency",
                       base::TimeTicks::Now() - query_start_time_);
   SwapResults(&new_results);
@@ -231,4 +234,17 @@
   }
 }
 
+void ZeroStateFileProvider::AppendFakeSearchResults(Results* results) {
+  constexpr int kTotalFakeFiles = 3;
+  for (int i = 0; i < kTotalFakeFiles; ++i) {
+    results->emplace_back(std::make_unique<FileResult>(
+        kSchema,
+        base::FilePath(FILE_PATH_LITERAL(
+            base::StrCat({"Fake-file-", base::NumberToString(i), ".png"}))),
+        u"-", ash::AppListSearchResultType::kZeroStateFile,
+        ash::SearchResultDisplayType::kContinue, 0.1f, std::u16string(),
+        FileResult::Type::kFile, profile_));
+  }
+}
+
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
index 03f7219..0ebb7fa 100644
--- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
+++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider.h
@@ -70,6 +70,10 @@
   // paths are removed from the model.
   void SetSearchResults(ValidAndInvalidResults results);
 
+  // TODO(crbug.com/1349618): Remove this once the Continue tast test does not
+  // rely on it.
+  void AppendFakeSearchResults(Results* results);
+
   void OnProtoInitialized(ReadStatus status);
 
   // The reference to profile to get ZeroStateFileProvider service.
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index 86704e4..fa18eed1 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -38,10 +38,6 @@
 class Profile;
 struct WebAppInstallInfo;
 
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-class SettingsOverriddenDialogController;
-#endif
-
 namespace base {
 class FilePath;
 }
@@ -296,6 +292,9 @@
 
 #endif  // BUILDFLAG(IS_WIN)
 
+// TODO(crbug.com/1324288): Move extensions dialogs to
+// c/b/ui/extensions/extensions_dialogs.h
+
 // Displays a dialog to notify the user that the extension installation is
 // blocked due to policy. It also show additional information from administrator
 // if it exists.
@@ -324,28 +323,6 @@
     base::OnceClosure done_callback);
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
 
-// TODO(crbug.com/1324288): Move extensions dialogs to
-// c/b/ui/extensions/extensions_dialogs.h
-// TODO(devlin): Put more extension-y bits in this block - currently they're
-// unguarded.
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-// Shows the dialog indicating that an extension has overridden a setting.
-void ShowExtensionSettingsOverriddenDialog(
-    std::unique_ptr<SettingsOverriddenDialogController> controller,
-    Browser* browser);
-
-// Modal dialog shown to Enhanced Safe Browsing users before the extension
-// install dialog if the extension is not included in the Safe Browsing CRX
-// allowlist.
-//
-// `callback` will be invoked with `true` if the user accepts or `false` if the
-// user cancels the dialog.
-void ShowExtensionInstallFrictionDialog(
-    content::WebContents* contents,
-    base::OnceCallback<void(bool)> callback);
-
-#endif
-
 // Returns a OnceClosure that client code can call to close the device chooser.
 // This OnceClosure references the actual dialog as a WeakPtr, so it's safe to
 // call at any point.
diff --git a/chrome/browser/ui/extensions/extensions_dialogs.h b/chrome/browser/ui/extensions/extensions_dialogs.h
index 6d255b8..d265b41 100644
--- a/chrome/browser/ui/extensions/extensions_dialogs.h
+++ b/chrome/browser/ui/extensions/extensions_dialogs.h
@@ -8,17 +8,41 @@
 #include "base/callback_forward.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "extensions/buildflags/buildflags.h"
 #include "extensions/common/extension_id.h"
 #include "ui/gfx/native_widget_types.h"
 
+#if !BUILDFLAG(ENABLE_EXTENSIONS)
+#error "Extensions must be enabled"
+#endif
+
 class Browser;
 
+namespace content {
+class WebContents;
+}
+
 namespace gfx {
 class ImageSkia;
 }  // namespace gfx
 
+class SettingsOverriddenDialogController;
+
 namespace extensions {
 
+// Shows a modal dialog to Enhanced Safe Browsing users before the extension
+// install dialog if the extension is not included in the Safe Browsing CRX
+// allowlist. `callback` will be invoked with `true` if the user accepts or
+// `false` if the user cancels the dialog.
+void ShowExtensionInstallFrictionDialog(
+    content::WebContents* contents,
+    base::OnceCallback<void(bool)> callback);
+
+// Shows a dialog indicating that an extension has overridden a setting.
+void ShowExtensionSettingsOverriddenDialog(
+    std::unique_ptr<SettingsOverriddenDialogController> controller,
+    Browser* browser);
+
 // Shows a dialog when extensions require a refresh for their action
 // to be run or blocked. The dialog content is based on whether caller
 // `is_updating_permissions`. When the dialog is accepted, `callback` is
diff --git a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
index 8d3b883..23d38aa 100644
--- a/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
+++ b/chrome/browser/ui/extensions/settings_api_bubble_helpers.cc
@@ -12,12 +12,12 @@
 #include "chrome/browser/extensions/settings_api_bubble_delegate.h"
 #include "chrome/browser/extensions/settings_api_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/extensions/extension_message_bubble_bridge.h"
 #include "chrome/browser/ui/extensions/extension_settings_overridden_dialog.h"
 #include "chrome/browser/ui/extensions/extensions_container.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/browser/ui/extensions/settings_overridden_params_providers.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
@@ -153,7 +153,7 @@
   if (!dialog->ShouldShow())
     return;
 
-  chrome::ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
+  ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
 #endif
 }
 
@@ -201,7 +201,7 @@
   if (!dialog->ShouldShow())
     return;
 
-  chrome::ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
+  ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarManager.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarManager.java
index 55bb7a1..f689ae6 100644
--- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarManager.java
+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarManager.java
@@ -23,6 +23,8 @@
 import org.chromium.base.ApplicationStatus.ActivityStateListener;
 import org.chromium.base.UnownedUserData;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.supplier.ObservableSupplier;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
 import org.chromium.ui.base.WindowAndroid;
 
@@ -90,6 +92,8 @@
             updateView();
         }
     };
+    private final ObservableSupplierImpl<Boolean> mIsShowingSupplier =
+            new ObservableSupplierImpl<>();
 
     /**
      * Constructs a SnackbarManager to show snackbars in the given window.
@@ -110,6 +114,8 @@
                 || ApplicationStatus.getStateForActivity(mActivity) == ActivityState.RESUMED) {
             onStart();
         }
+
+        mIsShowingSupplier.set(isShowing());
     }
 
     @Override
@@ -239,6 +245,13 @@
     }
 
     /**
+     * @return Supplier of whether the snackbar is showing
+     */
+    public ObservableSupplier<Boolean> isShowingSupplier() {
+        return mIsShowingSupplier;
+    }
+
+    /**
      * @return Whether there is a snackbar on screen.
      */
     public boolean isShowing() {
@@ -284,6 +297,8 @@
                 mView.announceforAccessibility();
             }
         }
+
+        mIsShowingSupplier.set(isShowing());
     }
 
     @VisibleForTesting
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarTest.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarTest.java
index 6f3ebea1..2f44293d 100644
--- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarTest.java
+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarTest.java
@@ -297,6 +297,40 @@
                         && mManager.getCurrentSnackbarViewForTesting().mParent == sMainParent);
     }
 
+    @Test
+    @SmallTest
+    public void testSupplier_BeforeShowing() {
+        final Snackbar snackbar = Snackbar.make(
+                "stack", mDismissController, Snackbar.TYPE_ACTION, Snackbar.UMA_TEST_SNACKBAR);
+        pollSnackbarCondition(
+                "Snackbar isShowing() and isShowingSupplier().get() values are not both false before showing snackbar.",
+                () -> !mManager.isShowing() && !mManager.isShowingSupplier().get());
+    }
+
+    @Test
+    @SmallTest
+    public void testSupplier_WhileShowing() {
+        final Snackbar snackbar = Snackbar.make(
+                "stack", mDismissController, Snackbar.TYPE_ACTION, Snackbar.UMA_TEST_SNACKBAR);
+        PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> mManager.showSnackbar(snackbar));
+        pollSnackbarCondition(
+                "Snackbar isShowing() and isShowingSupplier().get() values are not both true while snackbar is showing.",
+                () -> mManager.isShowing() && mManager.isShowingSupplier().get());
+    }
+
+    @Test
+    @SmallTest
+    public void testSupplier_AfterShowing() {
+        final Snackbar snackbar = Snackbar.make(
+                "stack", mDismissController, Snackbar.TYPE_ACTION, Snackbar.UMA_TEST_SNACKBAR);
+        PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> mManager.showSnackbar(snackbar));
+        PostTask.runOrPostTask(
+                UiThreadTaskTraits.DEFAULT, () -> mManager.dismissSnackbars(mDismissController));
+        pollSnackbarCondition(
+                "Snackbar isShowing() and isShowingSupplier().get() values are not both false after dismissing snackbar.",
+                () -> !mManager.isShowing() && !mManager.isShowingSupplier().get());
+    }
+
     void pollSnackbarCondition(String message, Supplier<Boolean> condition) {
         CriteriaHelper.pollUiThread(condition::get, message);
     }
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc
index 60e37aa..e072ad4 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.cc
+++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -26,6 +26,7 @@
 #if BUILDFLAG(IS_WIN)
 #include "base/win/shortcut.h"
 #include "base/win/windows_version.h"
+#include "chrome/installer/util/taskbar_util.h"
 #endif  // BUILDFLAG(IS_WIN)
 
 namespace chrome {
@@ -129,9 +130,10 @@
         prefs::kWebAppCreateInAppsMenu);
   }
 
-  // Win10 actively prevents creating shortcuts on the taskbar so we eliminate
-  // that option from the dialog.
-  if (base::win::CanPinShortcutToTaskbar()) {
+  // Only include the pin-to-taskbar option when running on versions of Windows
+  // that support pinning.
+  if (CanPinShortcutToTaskbar()) {
+    // TODO(crbug.com/1348764): Remove pre-Win7 code and string.
     quick_launch_check_box =
         AddCheckbox((version >= base::win::Version::WIN7)
                         ? l10n_util::GetStringUTF16(IDS_PIN_TO_TASKBAR_CHKBOX)
diff --git a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view.cc
index 8263862..b04bcc5 100644
--- a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view.cc
@@ -34,8 +34,6 @@
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/layout_provider.h"
 
-namespace chrome {
-
 namespace {
 
 void AutoConfirmDialog(base::OnceCallback<void(bool)> callback) {
@@ -55,6 +53,8 @@
 
 }  // namespace
 
+namespace extensions {
+
 void ShowExtensionInstallFrictionDialog(
     content::WebContents* contents,
     base::OnceCallback<void(bool)> callback) {
@@ -72,7 +72,7 @@
       ->Show();
 }
 
-}  // namespace chrome
+}  // namespace extensions
 
 namespace {
 
diff --git a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc
index 42b8ce76..5040489 100644
--- a/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_friction_dialog_view_browsertest.cc
@@ -11,9 +11,9 @@
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
 #include "chrome/browser/ui/tabs/tab_enums.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/common/url_constants.h"
@@ -38,7 +38,7 @@
   ExtensionInstallFrictionDialogTest() = default;
 
   void ShowUi(const std::string& name) override {
-    chrome::ShowExtensionInstallFrictionDialog(
+    extensions::ShowExtensionInstallFrictionDialog(
         browser()->tab_strip_model()->GetActiveWebContents(),
         base::DoNothing());
   }
diff --git a/chrome/browser/ui/views/extensions/settings_overridden_dialog_view.cc b/chrome/browser/ui/views/extensions/settings_overridden_dialog_view.cc
index aa432c0..354c39d 100644
--- a/chrome/browser/ui/views/extensions/settings_overridden_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/settings_overridden_dialog_view.cc
@@ -19,6 +19,18 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/fill_layout.h"
 
+namespace extensions {
+
+void ShowExtensionSettingsOverriddenDialog(
+    std::unique_ptr<SettingsOverriddenDialogController> controller,
+    Browser* browser) {
+  // Note: ownership is taken by the view hierarchy.
+  auto* dialog_view = new SettingsOverriddenDialogView(std::move(controller));
+  dialog_view->Show(browser->window()->GetNativeWindow());
+}
+
+}  // namespace extensions
+
 SettingsOverriddenDialogView::SettingsOverriddenDialogView(
     std::unique_ptr<SettingsOverriddenDialogController> controller)
     : controller_(std::move(controller)) {
@@ -104,15 +116,3 @@
 
 BEGIN_METADATA(SettingsOverriddenDialogView, views::DialogDelegateView)
 END_METADATA
-
-namespace chrome {
-
-void ShowExtensionSettingsOverriddenDialog(
-    std::unique_ptr<SettingsOverriddenDialogController> controller,
-    Browser* browser) {
-  // Note: ownership is taken by the view hierarchy.
-  auto* dialog_view = new SettingsOverriddenDialogView(std::move(controller));
-  dialog_view->Show(browser->window()->GetNativeWindow());
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index 37d0add..41e2c381 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -202,8 +202,16 @@
 }
 
 // Tests that the custom tab bar is visible in fullscreen mode.
+// TODO(crbug.com/1349592): Flaky on linux-wayland-rel and linux-lacros-rel
+#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
+#define MAYBE_CustomTabBarIsVisibleInFullscreen \
+  DISABLED_CustomTabBarIsVisibleInFullscreen
+#else
+#define MAYBE_CustomTabBarIsVisibleInFullscreen \
+  CustomTabBarIsVisibleInFullscreen
+#endif
 IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewBrowserTest,
-                       CustomTabBarIsVisibleInFullscreen) {
+                       MAYBE_CustomTabBarIsVisibleInFullscreen) {
   InstallAndLaunchBookmarkApp();
 
   ASSERT_TRUE(
diff --git a/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.cc b/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.cc
index f4642f52..889c1159 100644
--- a/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.cc
+++ b/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.cc
@@ -178,8 +178,8 @@
     log_router->UnregisterReceiver(this);
 }
 
-void InternalsUIHandler::LogEntry(const base::Value& entry) {
-  if (!registered_with_log_router_ || entry.is_none())
+void InternalsUIHandler::LogEntry(const base::Value::Dict& entry) {
+  if (!registered_with_log_router_)
     return;
   FireWebUIListener("add-structured-log", entry);
 }
diff --git a/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h b/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
index 726e459e..ae019503 100644
--- a/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
+++ b/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
@@ -78,7 +78,7 @@
   void OnJavascriptDisallowed() override;
 
   // LogReceiver implementation.
-  void LogEntry(const base::Value& entry) override;
+  void LogEntry(const base::Value::Dict& entry) override;
 
   void StartSubscription();
   void EndSubscription();
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index 970cdd0b..a57081ea 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -61,11 +61,11 @@
 const double kPowerLevelHigh = 50;
 const double kPowerLevelLow = 2;
 
-bool GetString(const base::Value& dict,
+bool GetString(const base::Value::Dict& dict,
                base::StringPiece key,
                std::string* result) {
   CHECK(result);
-  const std::string* value = dict.GetDict().FindString(key);
+  const std::string* value = dict.FindString(key);
   if (value) {
     *result = *value;
   }
@@ -107,7 +107,7 @@
 
 void DeviceEmulatorMessageHandler::BluetoothObserver::DeviceAdded(
     const dbus::ObjectPath& object_path) {
-  base::Value device = owner_->GetDeviceInfo(object_path);
+  base::Value::Dict device = owner_->GetDeviceInfo(object_path);
 
   // Request to add the device to the view's list of devices.
   owner_->FireWebUIListener("bluetooth-device-added", device);
@@ -177,18 +177,17 @@
 
 void DeviceEmulatorMessageHandler::PowerObserver::PowerChanged(
     const power_manager::PowerSupplyProperties& proto) {
-  base::DictionaryValue power_properties;
+  base::Value::Dict power_properties;
 
-  power_properties.GetDict().Set("battery_percent",
-                                 int(proto.battery_percent()));
-  power_properties.GetDict().Set("battery_state", int(proto.battery_state()));
-  power_properties.GetDict().Set("external_power", int(proto.external_power()));
-  power_properties.GetDict().Set("battery_time_to_empty_sec",
-                                 int(proto.battery_time_to_empty_sec()));
-  power_properties.GetDict().Set("battery_time_to_full_sec",
-                                 int(proto.battery_time_to_full_sec()));
-  power_properties.GetDict().Set("external_power_source_id",
-                                 proto.external_power_source_id());
+  power_properties.Set("battery_percent", int(proto.battery_percent()));
+  power_properties.Set("battery_state", int(proto.battery_state()));
+  power_properties.Set("external_power", int(proto.external_power()));
+  power_properties.Set("battery_time_to_empty_sec",
+                       int(proto.battery_time_to_empty_sec()));
+  power_properties.Set("battery_time_to_full_sec",
+                       int(proto.battery_time_to_full_sec()));
+  power_properties.Set("external_power_source_id",
+                       proto.external_power_source_id());
 
   owner_->FireWebUIListener("power-properties-updated", power_properties);
 }
@@ -247,14 +246,14 @@
           dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));
 
   // Get each device's properties.
-  base::Value devices(base::Value::Type::LIST);
+  base::Value::List devices;
   for (const dbus::ObjectPath& path : paths)
     devices.Append(GetDeviceInfo(path));
 
   base::Value predefined_devices =
       fake_bluetooth_device_client_->GetBluetoothDevicesAsDictionaries();
 
-  base::Value pairing_method_options(base::Value::Type::LIST);
+  base::Value::List pairing_method_options;
   pairing_method_options.Append(
       bluez::FakeBluetoothDeviceClient::kPairingMethodNone);
   pairing_method_options.Append(
@@ -262,7 +261,7 @@
   pairing_method_options.Append(
       bluez::FakeBluetoothDeviceClient::kPairingMethodPassKey);
 
-  base::Value pairing_action_options(base::Value::Type::LIST);
+  base::Value::List pairing_action_options;
   pairing_action_options.Append(
       bluez::FakeBluetoothDeviceClient::kPairingActionDisplay);
   pairing_action_options.Append(
@@ -272,13 +271,11 @@
   pairing_action_options.Append(
       bluez::FakeBluetoothDeviceClient::kPairingActionFail);
 
-  base::Value info(base::Value::Type::DICTIONARY);
-  info.GetDict().Set("predefined_devices", std::move(predefined_devices));
-  info.GetDict().Set("devices", std::move(devices));
-  info.GetDict().Set("pairing_method_options",
-                     std::move(pairing_method_options));
-  info.GetDict().Set("pairing_action_options",
-                     std::move(pairing_action_options));
+  base::Value::Dict info;
+  info.Set("predefined_devices", std::move(predefined_devices));
+  info.Set("devices", std::move(devices));
+  info.Set("pairing_method_options", std::move(pairing_method_options));
+  info.Set("pairing_action_options", std::move(pairing_action_options));
 
   // Send the list of devices to the view.
   FireWebUIListener("bluetooth-info-updated", info);
@@ -311,13 +308,12 @@
 
   const base::Value& device_value = args[0];
   CHECK(device_value.is_dict());
-  const base::DictionaryValue& device_dict =
-      base::Value::AsDictionaryValue(device_value);
-  audio_node.is_input = device_dict.GetDict().FindBool("isInput").value();
+  const base::Value::Dict& device_dict = device_value.GetDict();
+  audio_node.is_input = device_dict.FindBool("isInput").value();
   CHECK(GetString(device_dict, "deviceName", &audio_node.device_name));
   CHECK(GetString(device_dict, "type", &audio_node.type));
   CHECK(GetString(device_dict, "name", &audio_node.name));
-  audio_node.active = device_dict.GetDict().FindBool("active").value();
+  audio_node.active = device_dict.FindBool("active").value();
 
   std::string tmp_id;
   CHECK(GetString(device_dict, "id", &tmp_id));
@@ -565,8 +561,7 @@
 
   const base::Value& device_value = args[0];
   CHECK(device_value.is_dict());
-  const base::DictionaryValue& device_dict =
-      base::Value::AsDictionaryValue(device_value);
+  const base::Value::Dict& device_dict = device_value.GetDict();
   CHECK(GetString(device_dict, "path", &props.device_path));
   CHECK(GetString(device_dict, "name", &props.device_name));
   CHECK(GetString(device_dict, "alias", &props.device_alias));
@@ -575,12 +570,12 @@
   CHECK(GetString(device_dict, "pairingAuthToken", &props.pairing_auth_token));
   CHECK(GetString(device_dict, "pairingAction", &props.pairing_action));
 
-  absl::optional<int> class_value = device_dict.GetDict().FindInt("classValue");
+  absl::optional<int> class_value = device_dict.FindInt("classValue");
   CHECK(class_value);
   props.device_class = *class_value;
 
-  props.is_trusted = device_dict.GetDict().FindBool("isTrusted").value();
-  props.incoming = device_dict.GetDict().FindBool("incoming").value();
+  props.is_trusted = device_dict.FindBool("isTrusted").value();
+  props.incoming = device_dict.FindBool("incoming").value();
 
   // Create the device and store it in the FakeBluetoothDeviceClient's observed
   // list of devices.
@@ -590,7 +585,7 @@
   return props.device_path;
 }
 
-base::Value DeviceEmulatorMessageHandler::GetDeviceInfo(
+base::Value::Dict DeviceEmulatorMessageHandler::GetDeviceInfo(
     const dbus::ObjectPath& object_path) {
   // Get the device's properties.
   bluez::FakeBluetoothDeviceClient::Properties* props =
@@ -598,28 +593,28 @@
   bluez::FakeBluetoothDeviceClient::SimulatedPairingOptions* options =
       fake_bluetooth_device_client_->GetPairingOptions(object_path);
 
-  base::Value device(base::Value::Type::DICTIONARY);
-  device.GetDict().Set("path", object_path.value());
-  device.GetDict().Set("name", props->name.value());
-  device.GetDict().Set("alias", props->alias.value());
-  device.GetDict().Set("address", props->address.value());
+  base::Value::Dict device;
+  device.Set("path", object_path.value());
+  device.Set("name", props->name.value());
+  device.Set("alias", props->alias.value());
+  device.Set("address", props->address.value());
   if (options) {
-    device.GetDict().Set("pairingMethod", options->pairing_method);
-    device.GetDict().Set("pairingAuthToken", options->pairing_auth_token);
-    device.GetDict().Set("pairingAction", options->pairing_action);
+    device.Set("pairingMethod", options->pairing_method);
+    device.Set("pairingAuthToken", options->pairing_auth_token);
+    device.Set("pairingAction", options->pairing_action);
   } else {
-    device.GetDict().Set("pairingMethod", "");
-    device.GetDict().Set("pairingAuthToken", "");
-    device.GetDict().Set("pairingAction", "");
+    device.Set("pairingMethod", "");
+    device.Set("pairingAuthToken", "");
+    device.Set("pairingAction", "");
   }
-  device.GetDict().Set("classValue", int(props->bluetooth_class.value()));
-  device.GetDict().Set("isTrusted", bool(props->trusted.value()));
-  device.GetDict().Set("incoming", false);
+  device.Set("classValue", int(props->bluetooth_class.value()));
+  device.Set("isTrusted", bool(props->trusted.value()));
+  device.Set("incoming", false);
 
-  base::Value uuids(base::Value::Type::LIST);
+  base::Value::List uuids;
   for (const std::string& uuid : props->uuids.value())
     uuids.Append(uuid);
-  device.GetDict().Set("uuids", std::move(uuids));
+  device.Set("uuids", std::move(uuids));
 
   return device;
 }
@@ -666,17 +661,17 @@
 void DeviceEmulatorMessageHandler::UpdateAudioNodes() {
   // Get every active audio node and create a dictionary to
   // send it to JavaScript.
-  base::Value audio_nodes(base::Value::Type::LIST);
+  base::Value::List audio_nodes;
   for (const AudioNode& node :
        chromeos::FakeCrasAudioClient::Get()->node_list()) {
-    base::Value audio_node(base::Value::Type::DICTIONARY);
+    base::Value::Dict audio_node;
 
-    audio_node.GetDict().Set("isInput", node.is_input);
-    audio_node.GetDict().Set("id", base::NumberToString(node.id));
-    audio_node.GetDict().Set("deviceName", node.device_name);
-    audio_node.GetDict().Set("type", node.type);
-    audio_node.GetDict().Set("name", node.name);
-    audio_node.GetDict().Set("active", node.active);
+    audio_node.Set("isInput", node.is_input);
+    audio_node.Set("id", base::NumberToString(node.id));
+    audio_node.Set("deviceName", node.device_name);
+    audio_node.Set("type", node.type);
+    audio_node.Set("name", node.name);
+    audio_node.Set("active", node.active);
 
     audio_nodes.Append(std::move(audio_node));
   }
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
index 13994f4..3183d7bd 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.h
@@ -117,7 +117,7 @@
 
   // Builds a dictionary with each key representing a property of the device
   // with path |object_path|.
-  base::Value GetDeviceInfo(const dbus::ObjectPath& object_path);
+  base::Value::Dict GetDeviceInfo(const dbus::ObjectPath& object_path);
 
   void ConnectToBluetoothDevice(const std::string& address);
 
diff --git a/chrome/browser/ui/webui/chromeos/human_presence_internals_ui.cc b/chrome/browser/ui/webui/chromeos/human_presence_internals_ui.cc
index dd23422..7682ab9b 100644
--- a/chrome/browser/ui/webui/chromeos/human_presence_internals_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/human_presence_internals_ui.cc
@@ -94,26 +94,26 @@
 
 void HumanPresenceInternalsUIMessageHandler::OnLockOnLeaveResult(
     absl::optional<hps::HpsResultProto> state) {
-  base::DictionaryValue value;
+  base::Value::Dict value;
   if (state.has_value()) {
-    value.SetInteger("state", state->value());
-    value.SetInteger("inference_result", state->inference_result());
-    value.SetInteger("inference_result_valid", state->inference_result_valid());
+    value.Set("state", state->value());
+    value.Set("inference_result", state->inference_result());
+    value.Set("inference_result_valid", state->inference_result_valid());
   } else {
-    value.SetBoolean("disabled", true);
+    value.Set("disabled", true);
   }
   FireWebUIListener(hps::kHumanPresenceInternalsLockOnLeaveChangedEvent, value);
 }
 
 void HumanPresenceInternalsUIMessageHandler::OnSnoopingProtectionResult(
     absl::optional<hps::HpsResultProto> state) {
-  base::DictionaryValue value;
+  base::Value::Dict value;
   if (state.has_value()) {
-    value.SetInteger("state", state->value());
-    value.SetInteger("inference_result", state->inference_result());
-    value.SetInteger("inference_result_valid", state->inference_result_valid());
+    value.Set("state", state->value());
+    value.Set("inference_result", state->inference_result());
+    value.Set("inference_result_valid", state->inference_result_valid());
   } else {
-    value.SetBoolean("disabled", true);
+    value.Set("disabled", true);
   }
   FireWebUIListener(hps::kHumanPresenceInternalsSnoopingProtectionChangedEvent,
                     value);
@@ -140,8 +140,8 @@
 }
 
 void HumanPresenceInternalsUIMessageHandler::OnConnected(bool connected) {
-  base::DictionaryValue value;
-  value.SetBoolean("connected", connected);
+  base::Value::Dict value;
+  value.Set("connected", connected);
   FireWebUIListener(hps::kHumanPresenceInternalsConnectedEvent, value);
 
   if (connected) {
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/confirm_password_change_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/confirm_password_change_handler.cc
index 4fa9821d..342f974 100644
--- a/chrome/browser/ui/webui/chromeos/in_session_password_change/confirm_password_change_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/confirm_password_change_handler.cc
@@ -55,10 +55,10 @@
     const base::Value::List& params) {
   const std::string callback_id = params[0].GetString();
 
-  base::Value state(base::Value::Type::DICTIONARY);
-  state.SetBoolKey("showOldPasswordPrompt", scraped_old_password_.empty());
-  state.SetBoolKey("showNewPasswordPrompt", scraped_new_password_.empty());
-  state.SetBoolKey("showSpinner", show_spinner_initially_);
+  base::Value::Dict state;
+  state.Set("showOldPasswordPrompt", scraped_old_password_.empty());
+  state.Set("showNewPasswordPrompt", scraped_new_password_.empty());
+  state.Set("showSpinner", show_spinner_initially_);
 
   AllowJavascript();
   ResolveJavascriptCallback(base::Value(callback_id), state);
diff --git a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
index 2f26cd4..608f73c 100644
--- a/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.cc
@@ -146,9 +146,7 @@
 }
 
 void SyncConsentScreenHandler::Show(bool is_arc_restricted) {
-  auto* user_manager = user_manager::UserManager::Get();
   base::Value::Dict data;
-  data.Set("isChildAccount", user_manager->IsLoggedInAsChildUser());
   data.Set("isArcRestricted", is_arc_restricted);
   ShowInWebUI(std::move(data));
 }
diff --git a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom
index f427471..0b3f9eb 100644
--- a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom
+++ b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom
@@ -21,4 +21,23 @@
   // e.g. /foo/bar will return all child folders of ~/MyFiles/foo/bar
   GetChildFolders(mojo_base.mojom.FilePath path) => (
       array<mojo_base.mojom.FilePath> paths);
+
+  // A mapping exposed to the chrome://manage-mirrorsync webui to abstract away
+  // 3 classes of errors from their drive::FileError equivalents.
+  //  - When the DriveFS service is unavailable.
+  //  - Any other error has occurred.
+  //  - The syncing paths retrieval was successful.
+  enum GetSyncPathError {
+    kServiceUnavailable,
+    kSuccess,
+    kFailed,
+  };
+
+  // Returns a list of paths that are currently syncing via MirrorSync. These
+  // paths follow the same conventions as `GetChildFolders` such that they
+  // appear as parented at root but represent are actually relative to
+  // ~/MyFiles. See `GetChildFolders` for an example.
+  GetSyncingPaths() => (
+      GetSyncPathError error,
+      array<mojo_base.mojom.FilePath> syncing_paths);
 };
diff --git a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_dialog_browsertest.cc b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_dialog_browsertest.cc
index 629161c..8e30b0b 100644
--- a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_dialog_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_dialog_browsertest.cc
@@ -8,14 +8,23 @@
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "base/strings/strcat.h"
+#include "base/test/bind.h"
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
+#include "chrome/browser/ash/drive/drivefs_test_support.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom.h"
 #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "components/drive/drive_pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
@@ -24,7 +33,13 @@
 
 namespace chromeos {
 
+using base::test::RunOnceCallback;
+using testing::_;
+using testing::AllOf;
 using testing::ElementsAre;
+using testing::ElementsAreArray;
+using testing::Eq;
+using testing::IsEmpty;
 using testing::SizeIs;
 
 // The Mojo bindings for JS output a `base::FilePath` as an object with a 'path'
@@ -40,6 +55,61 @@
   return testing::ExplainMatchResult(matcher, paths, result_listener);
 }
 
+// Matcher to unwrap the `base::Value::Dict` from `getSyncingPaths` and extract
+// the "error" key. The value of this is cast into a `GetSyncPathError` to
+// compare.
+MATCHER_P(SyncPathError, matcher, "") {
+  absl::optional<int> error = arg.FindInt("error");
+  EXPECT_TRUE(error.has_value());
+  auto get_sync_path_error =
+      static_cast<manage_mirrorsync::mojom::PageHandler::GetSyncPathError>(
+          error.value());
+  return testing::ExplainMatchResult(matcher, get_sync_path_error,
+                                     result_listener);
+}
+
+// Matcher to unwrap the `base::Value::Dict` from `getSyncPaths` and extract the
+// "syncingPaths" key. This can be coupled wit the `MojoFilePaths` matcher to
+// perform element comparison on the resultant `base::Value::Dict` in the array.
+MATCHER_P(SyncingPaths, matcher, "") {
+  const base::Value::List* paths = arg.FindList("syncingPaths");
+  EXPECT_NE(paths, nullptr);
+  return testing::ExplainMatchResult(matcher, *paths, result_listener);
+}
+
+// Helper to observe the DriveIntegrationService for when mirroring is enabled.
+class DriveMirrorSyncStatusObserver
+    : public drive::DriveIntegrationServiceObserver {
+ public:
+  explicit DriveMirrorSyncStatusObserver(bool expected_status)
+      : expected_status_(expected_status) {
+    quit_closure_ = run_loop_.QuitClosure();
+  }
+
+  DriveMirrorSyncStatusObserver(const DriveMirrorSyncStatusObserver&) = delete;
+  DriveMirrorSyncStatusObserver& operator=(
+      const DriveMirrorSyncStatusObserver&) = delete;
+
+  ~DriveMirrorSyncStatusObserver() override = default;
+
+  void WaitForStatusChange() { run_loop_.Run(); }
+
+  void OnMirroringEnabled() override {
+    quit_closure_.Run();
+    EXPECT_TRUE(expected_status_);
+  }
+
+  void OnMirroringDisabled() override {
+    quit_closure_.Run();
+    EXPECT_FALSE(expected_status_);
+  }
+
+ private:
+  base::RunLoop run_loop_;
+  base::RepeatingClosure quit_closure_;
+  bool expected_status_ = false;
+};
+
 class ManageMirrorSyncDialogTest : public InProcessBrowserTest {
  public:
   ManageMirrorSyncDialogTest() {
@@ -52,15 +122,46 @@
   ManageMirrorSyncDialogTest& operator=(const ManageMirrorSyncDialogTest&) =
       delete;
 
+  void SetUpInProcessBrowserTestFixture() override {
+    create_drive_integration_service_ = base::BindRepeating(
+        &ManageMirrorSyncDialogTest::CreateDriveIntegrationService,
+        base::Unretained(this));
+    service_factory_for_test_ = std::make_unique<
+        drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>(
+        &create_drive_integration_service_);
+  }
+
+  drive::DriveIntegrationService* CreateDriveIntegrationService(
+      Profile* profile) {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    base::FilePath mount_point = profile->GetPath().Append("drivefs");
+    fake_drivefs_helpers_[profile] =
+        std::make_unique<drive::FakeDriveFsHelper>(profile, mount_point);
+    auto* integration_service = new drive::DriveIntegrationService(
+        profile, "", mount_point,
+        fake_drivefs_helpers_[profile]->CreateFakeDriveFsListenerFactory());
+    return integration_service;
+  }
+
+  // Show the MirrorSync dialog and wait for it to complete loading.
+  void ShowDialog() {
+    content::WebContentsAddedObserver observer;
+    ManageMirrorSyncDialog::Show(browser()->profile());
+    dialog_contents_ = observer.GetWebContents();
+    EXPECT_TRUE(content::WaitForLoadStop(dialog_contents_));
+    EXPECT_EQ(dialog_contents_->GetLastCommittedURL().host(),
+              chrome::kChromeUIManageMirrorSyncHost);
+  }
+
   void SetUpMyFilesAndDialog(std::vector<std::string> paths) {
     // Revoke the existing mount points and setup `temp_dir_` as the mount point
     // for ~/MyFiles.
+    my_files_dir_ = temp_dir_.GetPath().Append("MyFiles");
     storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
     storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
         file_manager::util::GetDownloadsMountPointName(browser()->profile()),
         storage::kFileSystemTypeLocal, storage::FileSystemMountOption(),
-        temp_dir_.GetPath());
-    my_files_dir_ = temp_dir_.GetPath();
+        my_files_dir_);
 
     // Create the supplied paths as individual folders. This ensures a path such
     // as foo/bar gets foo created and bar created as a child folder.
@@ -75,17 +176,56 @@
       }
     }
 
-    // Show the MirrorSync dialog and wait for it to complete loading.
-    content::WebContentsAddedObserver observer;
-    ManageMirrorSyncDialog::Show(browser()->profile());
-    dialog_contents_ = observer.GetWebContents();
-    EXPECT_TRUE(content::WaitForLoadStop(dialog_contents_));
-    EXPECT_EQ(dialog_contents_->GetLastCommittedURL().host(),
-              chrome::kChromeUIManageMirrorSyncHost);
+    ShowDialog();
   }
 
-  // Helper to send JS to the chrome://manage-mirrorsync dialog and extract it's
-  // response. Useful to ensure the API contract the Mojo exposes is valid.
+  drivefs::FakeDriveFs& SetUpMirrorSyncAndDialog(bool enabled) {
+    // Revoke the existing mount points and setup `temp_dir_` as the mount point
+    // for ~/MyFiles.
+    my_files_dir_ = temp_dir_.GetPath().Append("MyFiles");
+    storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
+    storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+        file_manager::util::GetDownloadsMountPointName(browser()->profile()),
+        storage::kFileSystemTypeLocal, storage::FileSystemMountOption(),
+        my_files_dir_);
+
+    // Toggle the MirrorSync preference to enable / disable the feature.
+    auto observer = std::make_unique<DriveMirrorSyncStatusObserver>(enabled);
+    auto* drive_service = drive::DriveIntegrationServiceFactory::FindForProfile(
+        browser()->profile());
+    drive_service->AddObserver(observer.get());
+    browser()->profile()->GetPrefs()->SetBoolean(
+        drive::prefs::kDriveFsEnableMirrorSync, enabled);
+    observer->WaitForStatusChange();
+    drive_service->RemoveObserver(observer.get());
+
+    ShowDialog();
+
+    return fake_drivefs_helpers_[browser()->profile()]->fake_drivefs();
+  }
+
+  // Returns a pair of std::vector where the first element contains a list of
+  // base::FilePaths that represent absolute paths parented at `my_files_dir_`
+  // and the second element contains the expected paths returned from
+  // `getSyncingPaths` i.e. with the leading `my_files_dir_` replaced with a "/"
+  // character. For example: CreateExpectedPaths({{"foo"}}) will have the
+  // following first element:
+  //   /MyFiles/foo
+  // And the second element will be:
+  //   /foo
+  std::pair<std::vector<base::FilePath>, std::vector<std::string>>
+  CreateExpectedPaths(std::vector<std::string> paths) {
+    std::vector<base::FilePath> absolute_paths;
+    std::vector<std::string> expected_paths;
+    for (const auto& path : paths) {
+      absolute_paths.push_back(my_files_dir_.Append(path));
+      expected_paths.push_back(base::StrCat({"/", path}));
+    }
+    return std::make_pair(absolute_paths, expected_paths);
+  }
+
+  // Helper to invoke the `getChildFolders` method on chrome://manage-mirrorsync
+  // dialog and extract it's response.
   base::Value::List GetChildFolders(const std::string& path) {
     const std::string js_expression = base::StrCat(
         {"((async () => { "
@@ -101,6 +241,20 @@
     return response_list.GetList().Clone();
   }
 
+  // Helper to invoke the `getSyncingPaths` method on chrome://manage-mirrorsync
+  // dialog and extract it's response.
+  base::Value::Dict GetSyncingPaths() {
+    const std::string js_expression =
+        "((async () => { "
+        "const {BrowserProxy} = await import('./browser_proxy.js');"
+        "const handler = BrowserProxy.getInstance().handler;"
+        "const response = await handler.getSyncingPaths();"
+        "return response; })())";
+    auto response = content::EvalJs(dialog_contents_, js_expression);
+    EXPECT_TRUE(response.value.is_dict());
+    return response.value.GetDict().Clone();
+  }
+
   void TearDown() override {
     InProcessBrowserTest::TearDown();
     storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
@@ -110,6 +264,13 @@
   base::ScopedTempDir temp_dir_;
   base::FilePath my_files_dir_;
   content::WebContents* dialog_contents_;
+
+  drive::DriveIntegrationServiceFactory::FactoryCallback
+      create_drive_integration_service_;
+  std::unique_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
+      service_factory_for_test_;
+  std::map<Profile*, std::unique_ptr<drive::FakeDriveFsHelper>>
+      fake_drivefs_helpers_;
 };
 
 IN_PROC_BROWSER_TEST_F(ManageMirrorSyncDialogTest, ExpectedScenarios) {
@@ -131,7 +292,7 @@
   {
     // Folders with no children should return an empty list.
     const auto& child_folders = GetChildFolders("/baz");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
   }
 }
 
@@ -141,25 +302,25 @@
   {
     // Not supplying a path should return an empty list.
     const auto& child_folders = GetChildFolders("");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
   }
 
   {
     // Path traversals should return an empty list.
     const auto& child_folders = GetChildFolders("/../../");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
   }
 
   {
     // Relative paths should are invalid, empty list is returned.
     const auto& child_folders = GetChildFolders("foo/bar");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
   }
 
   {
     // Non-existent directories should return an empty list.
     const auto& child_folders = GetChildFolders("/non-existant");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
   }
 }
 
@@ -188,7 +349,95 @@
   {
     // Supplied dot folders should return an empty list.
     const auto& child_folders = GetChildFolders("/baz/.Trash");
-    EXPECT_THAT(child_folders, SizeIs(0));
+    EXPECT_THAT(child_folders, IsEmpty());
+  }
+}
+
+using manage_mirrorsync::mojom::PageHandler;
+
+IN_PROC_BROWSER_TEST_F(ManageMirrorSyncDialogTest,
+                       GetSyncingPathsMirrorSyncEnabled) {
+  drivefs::FakeDriveFs& fake_drivefs =
+      SetUpMirrorSyncAndDialog(/*enabled=*/true);
+
+  {
+    // No paths currently syncing returns empty.
+    const auto& [mock_paths, expected_paths] = CreateExpectedPaths({});
+    EXPECT_CALL(fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(
+            RunOnceCallback<0>(drive::FileError::FILE_ERROR_OK, mock_paths));
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(syncing_paths,
+                AllOf(SyncPathError(PageHandler::GetSyncPathError::kSuccess),
+                      SyncingPaths(IsEmpty())));
+  }
+
+  {
+    // Single path being synced returns correctly.
+    const auto& [mock_paths, expected_paths] = CreateExpectedPaths({{"foo"}});
+    EXPECT_CALL(fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(
+            RunOnceCallback<0>(drive::FileError::FILE_ERROR_OK, mock_paths));
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(
+        syncing_paths,
+        AllOf(SyncPathError(PageHandler::GetSyncPathError::kSuccess),
+              SyncingPaths(MojoFilePaths(ElementsAreArray(expected_paths)))));
+  }
+
+  {
+    // Nested syncing path returns itself but not the parents.
+    const auto& [mock_paths, expected_paths] =
+        CreateExpectedPaths({{"foo/bar"}});
+    EXPECT_CALL(fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(
+            RunOnceCallback<0>(drive::FileError::FILE_ERROR_OK, mock_paths));
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(
+        syncing_paths,
+        AllOf(SyncPathError(PageHandler::GetSyncPathError::kSuccess),
+              SyncingPaths(MojoFilePaths(ElementsAreArray(expected_paths)))));
+  }
+
+  {
+    // Failure from retrieval of paths should return error + empty vector.
+    const auto& [mock_paths, expected_paths] = CreateExpectedPaths({});
+    EXPECT_CALL(fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(RunOnceCallback<0>(drive::FileError::FILE_ERROR_NOT_FOUND,
+                                     mock_paths));
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(syncing_paths,
+                AllOf(SyncPathError(PageHandler::GetSyncPathError::kFailed),
+                      SyncingPaths(IsEmpty())));
+  }
+
+  {
+    // Paths returned not parented at MyFiles should be ignored.
+    auto [mock_paths, expected_paths] = CreateExpectedPaths({{"baz"}});
+    mock_paths.push_back(base::FilePath("/ignore/dir"));
+    EXPECT_CALL(fake_drivefs, GetSyncingPaths(_))
+        .WillOnce(
+            RunOnceCallback<0>(drive::FileError::FILE_ERROR_OK, mock_paths));
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(
+        syncing_paths,
+        AllOf(SyncPathError(PageHandler::GetSyncPathError::kSuccess),
+              SyncingPaths(AllOf(SizeIs(1), MojoFilePaths(ElementsAreArray(
+                                                expected_paths))))));
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(ManageMirrorSyncDialogTest,
+                       GetSyncingPathsMirrorSyncDisabled) {
+  SetUpMirrorSyncAndDialog(/*enabled=*/false);
+
+  {
+    // MirrorSync not enabled should return kServiceUnavailable and empty paths.
+    const auto& syncing_paths = GetSyncingPaths();
+    EXPECT_THAT(
+        syncing_paths,
+        AllOf(SyncPathError(PageHandler::GetSyncPathError::kServiceUnavailable),
+              SyncingPaths(IsEmpty())));
   }
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.cc b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.cc
index 45b621f..2f09b0fe 100644
--- a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_piece.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 
 namespace chromeos {
@@ -61,7 +62,8 @@
     mojo::PendingReceiver<manage_mirrorsync::mojom::PageHandler>
         pending_page_handler,
     Profile* profile)
-    : my_files_dir_(file_manager::util::GetMyFilesFolderForProfile(profile)),
+    : profile_(profile),
+      my_files_dir_(file_manager::util::GetMyFilesFolderForProfile(profile)),
       receiver_{this, std::move(pending_page_handler)} {}
 
 ManageMirrorSyncPageHandler::~ManageMirrorSyncPageHandler() = default;
@@ -118,4 +120,50 @@
   std::move(callback).Run(std::move(child_folders));
 }
 
+using manage_mirrorsync::mojom::PageHandler;
+
+void ManageMirrorSyncPageHandler::GetSyncingPaths(
+    GetSyncingPathsCallback callback) {
+  drive::DriveIntegrationService* drive_service =
+      drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
+  if (drive_service == nullptr) {
+    LOG(ERROR) << "Drive service is not available";
+    std::move(callback).Run(PageHandler::GetSyncPathError::kServiceUnavailable,
+                            {});
+    return;
+  }
+
+  drive_service->GetSyncingPaths(
+      base::BindOnce(&ManageMirrorSyncPageHandler::OnGetSyncingPaths,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void ManageMirrorSyncPageHandler::OnGetSyncingPaths(
+    GetSyncingPathsCallback callback,
+    drive::FileError status,
+    const std::vector<base::FilePath>& syncing_paths) {
+  if (status != drive::FileError::FILE_ERROR_OK) {
+    LOG(ERROR) << "Failed retrieving sync paths: " << status;
+    const auto error =
+        (status == drive::FileError::FILE_ERROR_SERVICE_UNAVAILABLE)
+            ? PageHandler::GetSyncPathError::kServiceUnavailable
+            : PageHandler::GetSyncPathError::kFailed;
+    std::move(callback).Run(std::move(error), {});
+    return;
+  }
+
+  std::vector<base::FilePath> remapped_paths;
+  for (const base::FilePath& path : syncing_paths) {
+    if (!my_files_dir_.IsParent(path)) {
+      LOG(ERROR) << "Syncing path is not parented at MyFiles";
+      continue;
+    }
+    base::FilePath remapped_path("/");
+    my_files_dir_.AppendRelativePath(path, &remapped_path);
+    remapped_paths.push_back(std::move(remapped_path));
+  }
+  std::move(callback).Run(PageHandler::GetSyncPathError::kSuccess,
+                          std::move(remapped_paths));
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.h b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.h
index 6fe4a80..1337443 100644
--- a/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.h
+++ b/chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync_page_handler.h
@@ -9,8 +9,10 @@
 
 #include "base/callback.h"
 #include "base/files/file_path.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/webui/chromeos/manage_mirrorsync/manage_mirrorsync.mojom.h"
+#include "components/drive/file_errors.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -40,6 +42,8 @@
   void GetChildFolders(const base::FilePath& path,
                        GetChildFoldersCallback callback) override;
 
+  void GetSyncingPaths(GetSyncingPathsCallback callback) override;
+
  private:
   void OnDirectoryExists(const base::FilePath& absolute_path,
                          GetChildFoldersCallback callback,
@@ -48,6 +52,11 @@
   void OnGetChildFolders(GetChildFoldersCallback callback,
                          std::vector<base::FilePath> child_folders);
 
+  void OnGetSyncingPaths(GetSyncingPathsCallback callback,
+                         drive::FileError error,
+                         const std::vector<base::FilePath>& syncing_paths);
+
+  raw_ptr<Profile> profile_;
   const base::FilePath my_files_dir_;
   mojo::Receiver<manage_mirrorsync::mojom::PageHandler> receiver_;
   base::WeakPtrFactory<ManageMirrorSyncPageHandler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc
index 3d82e0c..a56abdbf 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_logs_handler.cc
@@ -24,15 +24,15 @@
 
 // Converts |log_message| to a raw dictionary value used as a JSON argument to
 // JavaScript functions.
-base::Value LogMessageToDictionary(const LogBuffer::LogMessage& log_message) {
-  base::Value dictionary(base::Value::Type::DICTIONARY);
-  dictionary.SetStringKey(kLogMessageTextKey, log_message.text);
-  dictionary.SetStringKey(
-      kLogMessageTimeKey,
-      base::TimeFormatTimeOfDayWithMilliseconds(log_message.time));
-  dictionary.SetStringKey(kLogMessageFileKey, log_message.file);
-  dictionary.SetIntKey(kLogMessageLineKey, log_message.line);
-  dictionary.SetIntKey(kLogMessageSeverityKey, log_message.severity);
+base::Value::Dict LogMessageToDictionary(
+    const LogBuffer::LogMessage& log_message) {
+  base::Value::Dict dictionary;
+  dictionary.Set(kLogMessageTextKey, log_message.text);
+  dictionary.Set(kLogMessageTimeKey,
+                 base::TimeFormatTimeOfDayWithMilliseconds(log_message.time));
+  dictionary.Set(kLogMessageFileKey, log_message.file);
+  dictionary.Set(kLogMessageLineKey, log_message.line);
+  dictionary.Set(kLogMessageSeverityKey, log_message.severity);
   return dictionary;
 }
 
@@ -65,7 +65,7 @@
   for (const auto& log : *LogBuffer::GetInstance()->logs()) {
     list.Append(LogMessageToDictionary(log));
   }
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(list)));
+  ResolveJavascriptCallback(callback_id, list);
 }
 
 void MultideviceLogsHandler::OnLogBufferCleared() {
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
index 65f3dd9..ec0b17f 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
@@ -259,7 +259,7 @@
 
 void MultidevicePhoneHubHandler::OnNotificationsRemoved(
     const base::flat_set<int64_t>& notification_ids) {
-  base::ListValue removed_notification_id_js_list;
+  base::Value::List removed_notification_id_js_list;
   for (const int64_t& id : notification_ids) {
     removed_notification_id_js_list.Append(static_cast<double>(id));
   }
@@ -297,10 +297,10 @@
 }
 
 void MultidevicePhoneHubHandler::OnCameraRollViewUiStateUpdated() {
-  base::Value camera_roll_dict(base::Value::Type::DICTIONARY);
-  camera_roll_dict.GetDict().Set(
-      "isCameraRollEnabled", fake_phone_hub_manager_->fake_camera_roll_manager()
-                                 ->is_camera_roll_enabled());
+  base::Value::Dict camera_roll_dict;
+  camera_roll_dict.Set("isCameraRollEnabled",
+                       fake_phone_hub_manager_->fake_camera_roll_manager()
+                           ->is_camera_roll_enabled());
   FireWebUIListener("camera-roll-ui-view-state-updated", camera_roll_dict);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
index 1fa51a5..23db4dd 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
@@ -46,13 +46,13 @@
       chromeos::ProfileHelper::Get()->GetUserByProfile(
           Profile::FromWebUI(web_ui()));
 
-  base::DictionaryValue response;
-  response.SetStringKey("email", user->GetDisplayEmail());
+  base::Value::Dict response;
+  response.Set("email", user->GetDisplayEmail());
 
   scoped_refptr<base::RefCountedMemory> image =
       chromeos::UserImageSource::GetUserImage(user->GetAccountId());
-  response.SetStringKey("profilePhotoUrl",
-                        webui::GetPngDataUrl(image->front(), image->size()));
+  response.Set("profilePhotoUrl",
+               webui::GetPngDataUrl(image->front(), image->size()));
 
   ResolveJavascriptCallback(base::Value(callback_id), response);
 }
diff --git a/chrome/browser/ui/webui/chromeos/network_logs_message_handler.cc b/chrome/browser/ui/webui/chromeos/network_logs_message_handler.cc
index d4fbbb3d..f5c6c8f 100644
--- a/chrome/browser/ui/webui/chromeos/network_logs_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/network_logs_message_handler.cc
@@ -52,9 +52,9 @@
   return bytes_written > 0;
 }
 
-bool GetBoolOrFalse(const base::Value& dict, const char* keyname) {
-  const base::Value* key = dict.FindKey(keyname);
-  return key && key->GetBool();
+bool GetBoolOrFalse(const base::Value::Dict& dict, const char* keyname) {
+  const auto key = dict.FindBool(keyname);
+  return key && *key;
 }
 
 }  // namespace
@@ -77,7 +77,7 @@
 void NetworkLogsMessageHandler::Respond(const std::string& callback_id,
                                         const std::string& result,
                                         bool is_error) {
-  base::Value response(base::Value::Type::LIST);
+  base::Value::List response;
   response.Append(result);
   response.Append(is_error);
   ResolveJavascriptCallback(base::Value(callback_id), response);
@@ -86,7 +86,7 @@
 void NetworkLogsMessageHandler::OnStoreLogs(const base::Value::List& list) {
   CHECK_EQ(2u, list.size());
   std::string callback_id = list[0].GetString();
-  const base::Value& options = list[1];
+  const base::Value::Dict& options = list[1].GetDict();
   AllowJavascript();
 
   if (GetBoolOrFalse(options, "systemLogs")) {
@@ -103,7 +103,7 @@
 
 void NetworkLogsMessageHandler::OnWriteSystemLogs(
     const std::string& callback_id,
-    base::Value&& options,
+    base::Value::Dict&& options,
     absl::optional<base::FilePath> syslogs_path) {
   if (!syslogs_path) {
     Respond(callback_id, "Error writing system logs file.", /*is_error=*/true);
@@ -114,7 +114,7 @@
 
 void NetworkLogsMessageHandler::MaybeWriteDebugLogs(
     const std::string& callback_id,
-    base::Value&& options) {
+    base::Value::Dict&& options) {
   if (GetBoolOrFalse(options, "debugLogs")) {
     if (!base::SysInfo::IsRunningOnChromeOS()) {
       Respond(callback_id, "Debug logs unavailable on Linux build.",
@@ -134,7 +134,7 @@
 
 void NetworkLogsMessageHandler::OnWriteDebugLogs(
     const std::string& callback_id,
-    base::Value&& options,
+    base::Value::Dict&& options,
     absl::optional<base::FilePath> logs_path) {
   if (!logs_path) {
     Respond(callback_id, "Error writing debug logs.", /*is_error=*/true);
@@ -145,7 +145,7 @@
 
 void NetworkLogsMessageHandler::MaybeWritePolicies(
     const std::string& callback_id,
-    base::Value&& options) {
+    base::Value::Dict&& options) {
   if (GetBoolOrFalse(options, "policies")) {
     std::string json_policies = GetJsonPolicies(web_ui());
     base::ThreadPool::PostTaskAndReplyWithResult(
diff --git a/chrome/browser/ui/webui/chromeos/network_logs_message_handler.h b/chrome/browser/ui/webui/chromeos/network_logs_message_handler.h
index 0b4cc16..42fa3e6 100644
--- a/chrome/browser/ui/webui/chromeos/network_logs_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/network_logs_message_handler.h
@@ -32,15 +32,15 @@
                bool is_error);
   void OnStoreLogs(const base::Value::List& list);
   void OnWriteSystemLogs(const std::string& callback_id,
-                         base::Value&& options,
+                         base::Value::Dict&& options,
                          absl::optional<base::FilePath> syslogs_path);
   void MaybeWriteDebugLogs(const std::string& callback_id,
-                           base::Value&& options);
+                           base::Value::Dict&& options);
   void OnWriteDebugLogs(const std::string& callback_id,
-                        base::Value&& options,
+                        base::Value::Dict&& options,
                         absl::optional<base::FilePath> logs_path);
   void MaybeWritePolicies(const std::string& callback_id,
-                          base::Value&& options);
+                          base::Value::Dict&& options);
   void OnWritePolicies(const std::string& callback_id, bool result);
   void OnWriteSystemLogsCompleted(const std::string& callback_id);
   void OnSetShillDebugging(const base::Value::List& list);
diff --git a/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc b/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc
index 8232b50..9d182d87 100644
--- a/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/onc_import_message_handler.cc
@@ -54,7 +54,7 @@
 void OncImportMessageHandler::Respond(const std::string& callback_id,
                                       const std::string& result,
                                       bool is_error) {
-  base::Value response(base::Value::Type::LIST);
+  base::Value::List response;
   response.Append(result);
   response.Append(is_error);
   ResolveJavascriptCallback(base::Value(callback_id), response);
diff --git a/chrome/browser/ui/webui/chromeos/power_ui.cc b/chrome/browser/ui/webui/chromeos/power_ui.cc
index 8c2e516..3014154 100644
--- a/chrome/browser/ui/webui/chromeos/power_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/power_ui.cc
@@ -98,7 +98,7 @@
     element.Set("externalPower", sample.external_power);
     element.Set("time", sample.time.ToJsTime());
 
-    js_power_supply_data.Append(base::Value(std::move(element)));
+    js_power_supply_data.Append(std::move(element));
   }
 
   base::Value::List js_system_resumed_data = GetJsSystemResumedData();
@@ -107,7 +107,7 @@
   data.Set("powerSupplyData", std::move(js_power_supply_data));
   data.Set("systemResumedData", std::move(js_system_resumed_data));
   const base::Value& callback_id = args[0];
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(data)));
+  ResolveJavascriptCallback(callback_id, data);
 }
 
 void PowerMessageHandler::OnGetCpuIdleData(const base::Value::List& args) {
@@ -129,7 +129,7 @@
   data.Set("idleStateData", std::move(js_idle_data));
   data.Set("systemResumedData", std::move(js_system_resumed_data));
   const base::Value& callback_id = args[0];
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(data)));
+  ResolveJavascriptCallback(callback_id, data);
 }
 
 void PowerMessageHandler::OnGetCpuFreqData(const base::Value::List& args) {
@@ -151,7 +151,7 @@
   data.Set("freqStateData", std::move(js_freq_data));
   data.Set("systemResumedData", std::move(js_system_resumed_data));
   const base::Value& callback_id = args[0];
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(data)));
+  ResolveJavascriptCallback(callback_id, data);
 }
 
 void PowerMessageHandler::OnGetProcessUsageData(const base::Value::List& args) {
@@ -171,11 +171,10 @@
     element.Set("cmdline", process_info.process_data.cmdline);
     element.Set("type", static_cast<int>(process_info.process_data.type));
     element.Set("powerUsageFraction", process_info.power_usage_fraction);
-    js_process_usages.Append(base::Value(std::move(element)));
+    js_process_usages.Append(std::move(element));
   }
 
-  ResolveJavascriptCallback(callback_id,
-                            base::Value(std::move(js_process_usages)));
+  ResolveJavascriptCallback(callback_id, js_process_usages);
 }
 
 base::Value::List PowerMessageHandler::GetJsSystemResumedData() {
@@ -189,7 +188,7 @@
     element.Set("sleepDuration", sample.sleep_duration.InMillisecondsF());
     element.Set("time", sample.time.ToJsTime());
 
-    data.Append(base::Value(std::move(element)));
+    data.Append(std::move(element));
   }
   return data;
 }
@@ -216,7 +215,7 @@
 
       js_sample_list.Append(std::move(js_sample));
     }
-    js_data.Append(base::Value(std::move(js_sample_list)));
+    js_data.Append(std::move(js_sample_list));
   }
   return js_data;
 }
diff --git a/chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.cc b/chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.cc
index 6e9ce60..d97135d 100644
--- a/chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.cc
@@ -24,10 +24,11 @@
   return service;
 }
 
-base::Value BuildShareList(const std::vector<smb_client::SmbUrl>& shares) {
-  base::Value shares_list(base::Value::Type::LIST);
+base::Value::List BuildShareList(
+    const std::vector<smb_client::SmbUrl>& shares) {
+  base::Value::List shares_list;
   for (const auto& share : shares) {
-    shares_list.Append(base::Value(share.GetWindowsUNCString()));
+    shares_list.Append(share.GetWindowsUNCString());
   }
   return shares_list;
 }
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
index b0e35bb..5ac964d 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -137,26 +137,26 @@
   if (!service || !service->IsEngineInitialized())
     return;
 
-  base::DictionaryValue args;
+  base::Value::Dict args;
   SyncUserSettings* user_settings = service->GetUserSettings();
   // Tell the UI layer which data types are registered/enabled by the user.
-  args.SetBoolKey("syncAllOsTypes", user_settings->IsSyncAllOsTypesEnabled());
+  args.Set("syncAllOsTypes", user_settings->IsSyncAllOsTypesEnabled());
   UserSelectableOsTypeSet registered_types =
       user_settings->GetRegisteredSelectableOsTypes();
   UserSelectableOsTypeSet selected_types = user_settings->GetSelectedOsTypes();
 
   for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) {
     std::string type_name = syncer::GetUserSelectableOsTypeName(type);
-    args.SetBoolPath(type_name + "Registered", registered_types.Has(type));
-    args.SetBoolPath(type_name + "Synced", selected_types.Has(type));
+    args.SetByDottedPath(type_name + "Registered", registered_types.Has(type));
+    args.SetByDottedPath(type_name + "Synced", selected_types.Has(type));
   }
 
   // Wallpaper sync status is fetched from prefs and is considered enabled if
   // all OS types are enabled; this mimics behavior of GetSelectedOsTypes().
-  args.SetBoolKey(kWallpaperEnabledKey,
-                  user_settings->IsSyncAllOsTypesEnabled() ||
-                      profile_->GetPrefs()->GetBoolean(
-                          chromeos::settings::prefs::kSyncOsWallpaper));
+  args.Set(kWallpaperEnabledKey,
+           user_settings->IsSyncAllOsTypesEnabled() ||
+               profile_->GetPrefs()->GetBoolean(
+                   chromeos::settings::prefs::kSyncOsWallpaper));
 
   FireWebUIListener("os-sync-prefs-changed", args);
 }
diff --git a/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
index 395417d..b429bf0 100644
--- a/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.cc
@@ -101,24 +101,25 @@
   return true;
 }
 
-void SetConstValue(base::Value* result) {
+void SetConstValue(base::Value::Dict* result) {
   DCHECK(result);
   int counter_max = static_cast<int>(COUNTER_MAX);
-  result->SetPath({"const", "counterMax"}, base::Value(counter_max));
+  result->SetByDottedPath("const.counterMax", counter_max);
 }
 
-void SetCpusValue(const std::vector<CpuInfo>& infos, base::Value* result) {
+void SetCpusValue(const std::vector<CpuInfo>& infos,
+                  base::Value::Dict* result) {
   DCHECK(result);
-  base::Value cpu_results(base::Value::Type::LIST);
+  base::Value::List cpu_results;
   for (const CpuInfo& cpu : infos) {
-    base::Value cpu_result(base::Value::Type::DICTIONARY);
-    cpu_result.SetKey("user", base::Value(cpu.user));
-    cpu_result.SetKey("kernel", base::Value(cpu.kernel));
-    cpu_result.SetKey("idle", base::Value(cpu.idle));
-    cpu_result.SetKey("total", base::Value(cpu.total));
+    base::Value::Dict cpu_result;
+    cpu_result.Set("user", cpu.user);
+    cpu_result.Set("kernel", cpu.kernel);
+    cpu_result.Set("idle", cpu.idle);
+    cpu_result.Set("total", cpu.total);
     cpu_results.Append(std::move(cpu_result));
   }
-  result->SetKey("cpus", std::move(cpu_results));
+  result->Set("cpus", std::move(cpu_results));
 }
 
 const double kBytesInKB = 1024;
@@ -132,44 +133,41 @@
 
 void SetMemValue(const base::SystemMemoryInfoKB& info,
                  const base::VmStatInfo& vmstat,
-                 base::Value* result) {
+                 base::Value::Dict* result) {
   DCHECK(result);
-  base::Value mem_result(base::Value::Type::DICTIONARY);
+  base::Value::Dict mem_result;
 
   // For values that may exceed the range of 32-bit signed integer, use double.
   double total = static_cast<double>(info.total) * kBytesInKB;
-  mem_result.SetKey("total", base::Value(total));
-  mem_result.SetKey("available", base::Value(GetAvailablePhysicalMemory(info)));
+  mem_result.Set("total", total);
+  mem_result.Set("available", GetAvailablePhysicalMemory(info));
   double swap_total = static_cast<double>(info.swap_total) * kBytesInKB;
-  mem_result.SetKey("swapTotal", base::Value(swap_total));
+  mem_result.Set("swapTotal", swap_total);
   double swap_free = static_cast<double>(info.swap_free) * kBytesInKB;
-  mem_result.SetKey("swapFree", base::Value(swap_free));
+  mem_result.Set("swapFree", swap_free);
 
-  mem_result.SetKey("pswpin", base::Value(ToCounter(vmstat.pswpin)));
-  mem_result.SetKey("pswpout", base::Value(ToCounter(vmstat.pswpout)));
+  mem_result.Set("pswpin", ToCounter(vmstat.pswpin));
+  mem_result.Set("pswpout", ToCounter(vmstat.pswpout));
 
-  result->SetKey("memory", std::move(mem_result));
+  result->Set("memory", std::move(mem_result));
 }
 
-void SetZramValue(const base::SwapInfo& info, base::Value* result) {
+void SetZramValue(const base::SwapInfo& info, base::Value::Dict* result) {
   DCHECK(result);
-  base::Value zram_result(base::Value::Type::DICTIONARY);
+  base::Value::Dict zram_result;
 
-  zram_result.SetKey("numReads", base::Value(ToCounter(info.num_reads)));
-  zram_result.SetKey("numWrites", base::Value(ToCounter(info.num_writes)));
+  zram_result.Set("numReads", ToCounter(info.num_reads));
+  zram_result.Set("numWrites", ToCounter(info.num_writes));
 
   // For values that may exceed the range of 32-bit signed integer, use double.
-  zram_result.SetKey("comprDataSize",
-                     base::Value(static_cast<double>(info.compr_data_size)));
-  zram_result.SetKey("origDataSize",
-                     base::Value(static_cast<double>(info.orig_data_size)));
-  zram_result.SetKey("memUsedTotal",
-                     base::Value(static_cast<double>(info.mem_used_total)));
+  zram_result.Set("comprDataSize", static_cast<double>(info.compr_data_size));
+  zram_result.Set("origDataSize", static_cast<double>(info.orig_data_size));
+  zram_result.Set("memUsedTotal", static_cast<double>(info.mem_used_total));
 
-  result->SetKey("zram", std::move(zram_result));
+  result->Set("zram", std::move(zram_result));
 }
 
-base::Value GetSysInfo() {
+base::Value::Dict GetSysInfo() {
   std::vector<CpuInfo> cpu_infos(base::SysInfo::NumberOfProcessors());
   if (!GetCpuInfo(&cpu_infos)) {
     DLOG(WARNING) << "Failed to get system CPU info.";
@@ -188,7 +186,7 @@
     DLOG(WARNING) << ("Failed to get system zram info.");
   }
 
-  base::Value result(base::Value::Type::DICTIONARY);
+  base::Value::Dict result;
   SetConstValue(&result);
   SetCpusValue(cpu_infos, &result);
   SetMemValue(mem_info, vmstat_info, &result);
@@ -228,7 +226,7 @@
 }
 
 void SysInternalsMessageHandler::ReplySysInfo(base::Value callback_id,
-                                              base::Value result) {
+                                              base::Value::Dict result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   ResolveJavascriptCallback(callback_id, result);
diff --git a/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
index 7a90f67..952637666 100644
--- a/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
+++ b/chrome/browser/ui/webui/chromeos/sys_internals/sys_internals_message_handler.h
@@ -60,7 +60,7 @@
   //   total (counter)
   // }
   //
-  void ReplySysInfo(base::Value callback_id, base::Value result);
+  void ReplySysInfo(base::Value callback_id, base::Value::Dict result);
 
   base::WeakPtrFactory<SysInternalsMessageHandler> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
index 6014b980..c0daf10c 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_contact_handler.cc
@@ -41,7 +41,7 @@
 // TODO(nohle): We should probably break up this dictionary into smaller
 // dictionaries corresponding to each contact-manager observer functions. This
 // will require changes at the javascript layer as well.
-base::Value ContactMessageToDictionary(
+base::Value::Dict ContactMessageToDictionary(
     absl::optional<bool> did_contacts_change_since_last_upload,
     const absl::optional<std::set<std::string>>& allowed_contact_ids,
     const absl::optional<std::vector<nearbyshare::proto::ContactRecord>>&
@@ -76,7 +76,7 @@
     dictionary.Set(kContactMessageNumUnreachableContactsKey,
                    int(*num_unreachable_contacts_filtered_out));
   }
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
index baf3349..5a01640a 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_http_handler.cc
@@ -56,15 +56,15 @@
 
 // Converts a RPC request/response to a raw dictionary value used as a
 // JSON argument to JavaScript functions.
-base::Value HttpMessageToDictionary(const base::Value& message,
-                                    Direction dir,
-                                    Rpc rpc) {
+base::Value::Dict HttpMessageToDictionary(const base::Value& message,
+                                          Direction dir,
+                                          Rpc rpc) {
   base::Value::Dict dictionary;
   dictionary.Set(kHttpMessageBodyKey, FormatAsJSON(message));
   dictionary.Set(kHttpMessageTimeKey, GetJavascriptTimestamp());
   dictionary.Set(kHttpMessageRpcKey, static_cast<int>(rpc));
   dictionary.Set(kHttpMessageDirectionKey, static_cast<int>(dir));
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_logs_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_logs_handler.cc
index e99a16e..ec7352e 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_logs_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_logs_handler.cc
@@ -20,7 +20,8 @@
 
 // Converts |log_message| to a raw dictionary value used as a JSON argument to
 // JavaScript functions.
-base::Value LogMessageToDictionary(const LogBuffer::LogMessage& log_message) {
+base::Value::Dict LogMessageToDictionary(
+    const LogBuffer::LogMessage& log_message) {
   base::Value::Dict dictionary;
   dictionary.Set(kLogMessageTextKey, log_message.text);
   dictionary.Set(kLogMessageTimeKey,
@@ -28,7 +29,7 @@
   dictionary.Set(kLogMessageFileKey, log_message.file);
   dictionary.Set(kLogMessageLineKey, log_message.line);
   dictionary.Set(kLogMessageSeverityKey, log_message.severity);
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 }  // namespace
 
@@ -59,7 +60,7 @@
   for (const auto& log : *LogBuffer::GetInstance()->logs()) {
     list.Append(LogMessageToDictionary(log));
   }
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(list)));
+  ResolveJavascriptCallback(callback_id, list);
 }
 
 void NearbyInternalsLogsHandler::OnLogBufferCleared() {
diff --git a/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc b/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc
index 3166853..4e13204 100644
--- a/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/nearby_internals_ui_trigger_handler.cc
@@ -167,30 +167,30 @@
 
 // Converts |status_code| to a raw dictionary value used as a JSON argument
 // to JavaScript functions.
-base::Value StatusCodeToDictionary(
+base::Value::Dict StatusCodeToDictionary(
     const NearbySharingService::StatusCodes status_code,
     TriggerEvent trigger_event) {
   base::Value::Dict dictionary;
   dictionary.Set(kStatusCodeKey, StatusCodeToString(status_code));
   dictionary.Set(kTriggerEventKey, TriggerEventToString(trigger_event));
   dictionary.Set(kTimeStampKey, GetJavascriptTimestamp());
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 
 // Converts |share_target| to a raw dictionary value used as a JSON argument
 // to JavaScript functions.
-base::Value ShareTargetToDictionary(const ShareTarget share_target) {
+base::Value::Dict ShareTargetToDictionary(const ShareTarget share_target) {
   base::Value::Dict share_target_dictionary;
   share_target_dictionary.Set(kShareTargetDeviceNamesKey,
                               share_target.device_name);
   share_target_dictionary.Set(kShareTargetIdKey, share_target.id.ToString());
   share_target_dictionary.Set(kTimeStampKey, GetJavascriptTimestamp());
-  return base::Value(std::move(share_target_dictionary));
+  return share_target_dictionary;
 }
 
 // Converts |id_to_share_target_map| to a raw dictionary value used as a JSON
 // argument to JavaScript functions.
-base::Value ShareTargetMapToList(
+base::Value::List ShareTargetMapToList(
     const base::flat_map<std::string, ShareTarget>& id_to_share_target_map) {
   base::Value::List share_target_list;
   share_target_list.reserve(id_to_share_target_map.size());
@@ -199,12 +199,12 @@
     share_target_list.Append(ShareTargetToDictionary(it.second));
   }
 
-  return base::Value(std::move(share_target_list));
+  return share_target_list;
 }
 
 // Converts |transfer_metadata| to a raw dictionary value used as a JSON
 // argument to JavaScript functions.
-base::Value TransferUpdateToDictionary(
+base::Value::Dict TransferUpdateToDictionary(
     const ShareTarget& share_target,
     const TransferMetadata& transfer_metadata) {
   base::Value::Dict dictionary;
@@ -213,15 +213,15 @@
   dictionary.Set(kTimeStampKey, GetJavascriptTimestamp());
   dictionary.Set(kShareTargetDeviceNamesKey, share_target.device_name);
   dictionary.Set(kShareTargetIdKey, share_target.id.ToString());
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 
-base::Value StatusBooleansToDictionary(const bool is_scanning,
-                                       const bool is_transferring,
-                                       const bool is_receiving_files,
-                                       const bool is_sending_files,
-                                       const bool is_conecting,
-                                       const bool is_in_high_visibility) {
+base::Value::Dict StatusBooleansToDictionary(const bool is_scanning,
+                                             const bool is_transferring,
+                                             const bool is_receiving_files,
+                                             const bool is_sending_files,
+                                             const bool is_conecting,
+                                             const bool is_in_high_visibility) {
   base::Value::Dict dictionary;
   dictionary.Set(kIsScanning, is_scanning);
   dictionary.Set(kIsTransferring, is_transferring);
@@ -230,7 +230,7 @@
   dictionary.Set(kIsConnecting, is_conecting);
   dictionary.Set(kIsInHighVisibility, is_in_high_visibility);
   dictionary.Set(kTimeStampKey, GetJavascriptTimestamp());
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
index dd7392b..8af9441 100644
--- a/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
+++ b/chrome/browser/ui/webui/nearby_internals/quick_pair/quick_pair_handler.cc
@@ -35,7 +35,7 @@
 
 // Converts |log_message| to a raw dictionary value used as a JSON argument to
 // JavaScript functions.
-base::Value LogMessageToDictionary(
+base::Value::Dict LogMessageToDictionary(
     const ash::quick_pair::LogBuffer::LogMessage& log_message) {
   base::Value::Dict dictionary;
   dictionary.Set(kLogMessageTextKey, log_message.text);
@@ -44,7 +44,7 @@
   dictionary.Set(kLogMessageFileKey, log_message.file);
   dictionary.Set(kLogMessageLineKey, log_message.line);
   dictionary.Set(kLogMessageSeverityKey, log_message.severity);
-  return base::Value(std::move(dictionary));
+  return dictionary;
 }
 }  // namespace
 
@@ -99,7 +99,7 @@
 void QuickPairHandler::HandleGetLogMessages(const base::Value::List& args) {
   AllowJavascript();
   const base::Value& callback_id = args[0];
-  base::Value list(base::Value::Type::LIST);
+  base::Value::List list;
   for (const auto& log : *ash::quick_pair::LogBuffer::GetInstance()->logs()) {
     list.Append(LogMessageToDictionary(log));
   }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index b0d5328..49ce3ee 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -97,7 +97,6 @@
 #if !defined(OFFICIAL_BUILD)
     {"dummyModulesEnabled", ntp_features::kNtpDummyModules},
 #endif
-    {"chromeCartModuleEnabled", ntp_features::kNtpChromeCartModule},
     {"photosModuleEnabled", ntp_features::kNtpPhotosModule},
     {"feedModuleEnabled", ntp_features::kNtpFeedModule},
 };
@@ -443,6 +442,7 @@
                        base::FeatureList::IsEnabled(nameFeature.second));
   }
   source->AddBoolean("recipeTasksModuleEnabled", IsRecipeTasksModuleEnabled());
+  source->AddBoolean("chromeCartModuleEnabled", IsCartModuleEnabled());
   source->AddString("photosModuleCustomArtWork",
                     base::GetFieldTrialParamValueByFeature(
                         ntp_features::kNtpPhotosModuleCustomizedOptInArtWork,
@@ -836,6 +836,7 @@
     anyModuleEnabled |= base::FeatureList::IsEnabled(nameFeature.second);
   }
   anyModuleEnabled |= IsRecipeTasksModuleEnabled();
+  anyModuleEnabled |= IsCartModuleEnabled();
   // Only enable modules if account credentials are available as most modules
   // won't have data to render otherwise. We can override this behavior with the
   // "--signed-out-ntp-modules" command line switch, e.g. to allow modules in
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
index e19dcd5..3c73d215 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -285,7 +285,8 @@
                        std::unique_ptr<base::DictionaryValue>* printer_info_out,
                        const base::DictionaryValue& printer_info) {
   ++(*call_count);
-  printer_info_out->reset(printer_info.DeepCopy());
+  *printer_info_out = base::DictionaryValue::From(
+      base::Value::ToUniquePtrValue(printer_info.Clone()));
 }
 
 std::string RefCountedMemoryToString(
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index ff6067a..7e368f2 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2022,7 +2022,6 @@
        IDS_SETTINGS_SEARCH_ENGINES_INACTIVE_SHORTCUTS},
       {"searchEnginesNoInactiveShortcuts",
        IDS_SETTINGS_SEARCH_ENGINES_NO_INACTIVE_SHORTCUTS},
-      {"searchEnginesOther", IDS_SETTINGS_SEARCH_ENGINES_OTHER_ENGINES},
       {"searchEnginesNoOtherEngines",
        IDS_SETTINGS_SEARCH_ENGINES_NO_OTHER_ENGINES},
       {"searchEnginesExtension", IDS_SETTINGS_SEARCH_ENGINES_EXTENSION_ENGINES},
@@ -2032,7 +2031,6 @@
       {"searchEnginesSearchEngine", IDS_SETTINGS_SEARCH_ENGINES_SEARCH_ENGINE},
       {"searchEnginesSiteOrPage", IDS_SETTINGS_SEARCH_ENGINES_SITE_OR_PAGE},
       {"searchEnginesInactiveSite", IDS_SETTINGS_SEARCH_ENGINES_INACTIVE_SITE},
-      {"searchEnginesKeyword", IDS_SETTINGS_SEARCH_ENGINES_KEYWORD},
       {"searchEnginesShortcut", IDS_SETTINGS_SEARCH_ENGINES_SHORTCUT},
       {"searchEnginesQueryURL", IDS_SETTINGS_SEARCH_ENGINES_QUERY_URL},
       {"searchEnginesQueryURLExplanation",
@@ -2060,8 +2058,6 @@
        IDS_SETTINGS_SEARCH_ENGINES_ADDITIONAL_EXTENSIONS},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
-  // TODO(crbug.com/1340259): Remove this and cleanup front-end code.
-  html_source->AddBoolean("isActiveSearchEnginesFlagEnabled", true);
 }
 
 void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
diff --git a/chrome/browser/ui/webui/signin_internals_ui.cc b/chrome/browser/ui/webui/signin_internals_ui.cc
index a06dec4..59aa930 100644
--- a/chrome/browser/ui/webui/signin_internals_ui.cc
+++ b/chrome/browser/ui/webui/signin_internals_ui.cc
@@ -122,10 +122,12 @@
   }
 }
 
-void SignInInternalsHandler::OnSigninStateChanged(const base::Value* info) {
-  FireWebUIListener("signin-info-changed", *info);
+void SignInInternalsHandler::OnSigninStateChanged(
+    const base::Value::Dict& info) {
+  FireWebUIListener("signin-info-changed", info);
 }
 
-void SignInInternalsHandler::OnCookieAccountsFetched(const base::Value* info) {
-  FireWebUIListener("update-cookie-accounts", *info);
+void SignInInternalsHandler::OnCookieAccountsFetched(
+    const base::Value::Dict& info) {
+  FireWebUIListener("update-cookie-accounts", info);
 }
diff --git a/chrome/browser/ui/webui/signin_internals_ui.h b/chrome/browser/ui/webui/signin_internals_ui.h
index 3a2320d9..9f8020b 100644
--- a/chrome/browser/ui/webui/signin_internals_ui.h
+++ b/chrome/browser/ui/webui/signin_internals_ui.h
@@ -37,10 +37,10 @@
   void HandleGetSignInInfo(const base::Value::List& args);
 
   // AboutSigninInternals::Observer::OnSigninStateChanged implementation.
-  void OnSigninStateChanged(const base::Value* info) override;
+  void OnSigninStateChanged(const base::Value::Dict& info) override;
 
   // Notification that the cookie accounts are ready to be displayed.
-  void OnCookieAccountsFetched(const base::Value* info) override;
+  void OnCookieAccountsFetched(const base::Value::Dict& info) override;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SIGNIN_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/webapks/webapks_handler.cc b/chrome/browser/ui/webui/webapks/webapks_handler.cc
index 336d6e3a1..77712f2 100644
--- a/chrome/browser/ui/webui/webapks/webapks_handler.cc
+++ b/chrome/browser/ui/webui/webapks/webapks_handler.cc
@@ -58,6 +58,7 @@
   result.SetStringKey("scope", webapk_info.scope);
   result.SetStringKey("manifestUrl", webapk_info.manifest_url);
   result.SetStringKey("manifestStartUrl", webapk_info.manifest_start_url);
+  result.SetStringKey("manifestId", webapk_info.manifest_id);
   result.SetStringKey("displayMode",
                       blink::DisplayModeToString(webapk_info.display));
   result.SetStringKey(
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command.cc b/chrome/browser/web_applications/commands/install_isolated_app_command.cc
index ecdcd35c..9ce9c8b 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command.cc
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command.cc
@@ -15,7 +15,11 @@
 #include "base/values.h"
 #include "chrome/browser/web_applications/commands/web_app_command.h"
 #include "chrome/browser/web_applications/web_app_data_retriever.h"
+#include "chrome/browser/web_applications/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_install_finalizer.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_url_loader.h"
+#include "components/webapps/browser/install_result_code.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "third_party/blink/public/common/manifest/manifest_util.h"
 #include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
@@ -26,11 +30,13 @@
 InstallIsolatedAppCommand::InstallIsolatedAppCommand(
     base::StringPiece url,
     WebAppUrlLoader& url_loader,
+    WebAppInstallFinalizer& install_finalizer,
     base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback)
     : WebAppCommand(WebAppCommandLock::CreateForAppAndWebContentsLock(
           base::flat_set<AppId>{"some random app id"})),
       url_(url),
       url_loader_(url_loader),
+      install_finalizer_(install_finalizer),
       data_retriever_(std::make_unique<WebAppDataRetriever>()) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
 
@@ -41,8 +47,6 @@
                     result == InstallIsolatedAppCommandResult::kOk);
                 return result;
               }).Then(std::move(callback));
-
-  weak_this_ = weak_factory_.GetWeakPtr();
 }
 
 void InstallIsolatedAppCommand::SetDataRetrieverForTesting(
@@ -71,13 +75,15 @@
     return;
   }
 
-  url_loader_.LoadUrl(
-      url, shared_web_contents(),
-      WebAppUrlLoader::UrlComparison::kIgnoreQueryParamsAndRef,
-      base::BindOnce(&InstallIsolatedAppCommand::OnLoadUrl, weak_this_));
+  url_loader_.LoadUrl(url, shared_web_contents(),
+                      WebAppUrlLoader::UrlComparison::kIgnoreQueryParamsAndRef,
+                      base::BindOnce(&InstallIsolatedAppCommand::OnLoadUrl,
+                                     weak_factory_.GetWeakPtr()));
 }
 
 void InstallIsolatedAppCommand::OnLoadUrl(WebAppUrlLoaderResult result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (!IsUrlLoadingResultSuccess(result)) {
     ReportFailure();
     return;
@@ -88,7 +94,7 @@
       /*bypass_service_worker_check=*/false,
       base::BindOnce(
           &InstallIsolatedAppCommand::OnCheckInstallabilityAndRetrieveManifest,
-          weak_this_));
+          weak_factory_.GetWeakPtr()));
 }
 
 void InstallIsolatedAppCommand::OnCheckInstallabilityAndRetrieveManifest(
@@ -123,7 +129,53 @@
   DCHECK(!manifest_url.is_empty())
       << "must not be empty if manifest is not empty.";
 
-  Report(/*success=*/true);
+  // TODO(kuragin): Fix order of calls to the data retrieve.
+  //
+  // The order should be:
+  //  1. |GetWebAppInstallInfo|
+  //  2. |CheckInstallabilityAndRetrieveManifest|
+  //  3. |GetIcons|
+  //
+  // See install from sync command unit-test for details:
+  // https://crsrc.org/c/chrome/browser/web_applications/commands/install_from_sync_command_unittest.cc;l=333;drc=ddce2fc4e67fd4500d29cbe5f4993b3fb8e4e2ba
+  data_retriever_->GetWebAppInstallInfo(
+      shared_web_contents(),
+      base::BindOnce(&InstallIsolatedAppCommand::OnGetWebAppInstallInfo,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void InstallIsolatedAppCommand::OnGetWebAppInstallInfo(
+    std::unique_ptr<WebAppInstallInfo> install_info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (install_info == nullptr) {
+    ReportFailure();
+    return;
+  }
+
+  install_finalizer_.FinalizeInstall(
+      *install_info,
+      // TODO(kuragin): Add Isolated app specific install source
+      // `WebappInstallSource::ISOLATED_APP_DEV_INSTALL`.
+      WebAppInstallFinalizer::FinalizeOptions{
+          /*install_surface=*/webapps::WebappInstallSource::MANAGEMENT_API,
+      },
+      base::BindOnce([](const AppId& unused_app_id,
+                        webapps::InstallResultCode unused_install_result_code,
+                        OsHooksErrors unused_os_hooks_errors) {
+        // TODO(kuragin): Implement error handling. Current implementation of
+        // the install finalizer doesn't allow to mock errors.
+        //
+        // See |FakeInstallFinalizer::FinalizeInstall| for details.
+      })
+          .Then(base::BindOnce(&InstallIsolatedAppCommand::DownloadIcons,
+                               weak_factory_.GetWeakPtr())));
+}
+
+void InstallIsolatedAppCommand::DownloadIcons() {
+  // TODO(kuragin): Find a way to test icons downloading and relationship with
+  // icon population in the web app install info. Implement icons downloading.
+  ReportSuccess();
 }
 
 void InstallIsolatedAppCommand::OnSyncSourceRemoved() {
@@ -138,6 +190,10 @@
   Report(/*success=*/false);
 }
 
+void InstallIsolatedAppCommand::ReportSuccess() {
+  Report(/*success=*/true);
+}
+
 void InstallIsolatedAppCommand::Report(bool success) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!callback_.is_null());
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command.h b/chrome/browser/web_applications/commands/install_isolated_app_command.h
index 67f9880..5beb12cc0 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command.h
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command.h
@@ -16,10 +16,12 @@
 #include "third_party/blink/public/mojom/manifest/manifest.mojom-forward.h"
 
 class GURL;
+struct WebAppInstallInfo;
 
 namespace web_app {
-class WebAppUrlLoader;
 class WebAppDataRetriever;
+class WebAppInstallFinalizer;
+class WebAppUrlLoader;
 
 enum class WebAppUrlLoaderResult;
 
@@ -30,9 +32,13 @@
 
 class InstallIsolatedAppCommand : public WebAppCommand {
  public:
+  // TODO(kuragin): Consider to create an instance of |GURL| instead of passing
+  // a string and probably introduce factory function in order to handle invalid
+  // urls.
   explicit InstallIsolatedAppCommand(
       base::StringPiece application_url,
       WebAppUrlLoader& url_loader,
+      WebAppInstallFinalizer& install_finalizer,
       base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback);
   ~InstallIsolatedAppCommand() override;
 
@@ -47,26 +53,30 @@
 
  private:
   void ReportFailure();
+  void ReportSuccess();
   void Report(bool success);
 
+  void DownloadIcons();
+
   void OnLoadUrl(WebAppUrlLoaderResult result);
   void OnCheckInstallabilityAndRetrieveManifest(
       blink::mojom::ManifestPtr opt_manifest,
       const GURL& manifest_url,
       bool valid_manifest_for_web_app,
       bool is_installable);
+  void OnGetWebAppInstallInfo(std::unique_ptr<WebAppInstallInfo> install_info);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
   std::string url_;
 
   WebAppUrlLoader& url_loader_;
+  WebAppInstallFinalizer& install_finalizer_;
 
   std::unique_ptr<WebAppDataRetriever> data_retriever_;
 
   base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback_;
 
-  base::WeakPtr<InstallIsolatedAppCommand> weak_this_;
   base::WeakPtrFactory<InstallIsolatedAppCommand> weak_factory_{this};
 };
 
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc b/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
index c5ee364..d6b3242 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/web_applications/commands/install_isolated_app_command.h"
 
+#include <map>
 #include <memory>
 #include <sstream>
 #include <vector>
@@ -12,26 +13,101 @@
 #include "base/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
+#include "base/strings/string_piece_forward.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_future.h"
 #include "chrome/browser/web_applications/test/fake_data_retriever.h"
+#include "chrome/browser/web_applications/test/fake_install_finalizer.h"
 #include "chrome/browser/web_applications/test/fake_web_app_provider.h"
 #include "chrome/browser/web_applications/test/test_web_app_url_loader.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_data_retriever.h"
+#include "chrome/browser/web_applications/web_app_install_finalizer.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_url_loader.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/webapps/browser/installable/installable_metrics.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/mojom/manifest/manifest.mojom-shared.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "url/gurl.h"
 
 namespace web_app {
 namespace {
 
+using ::testing::_;
 using ::testing::Eq;
+using ::testing::Field;
+using ::testing::IsFalse;
 using ::testing::Not;
+using ::testing::Pair;
+using ::testing::UnorderedElementsAre;
+
+blink::mojom::ManifestPtr CreateDefaultManifest() {
+  auto manifest = blink::mojom::Manifest::New();
+  manifest->start_url = GURL{"http://test.com/"},
+  manifest->scope = GURL{"http://test.com/scope"},
+  manifest->display = DisplayMode::kStandalone;
+  manifest->short_name = u"Manifest Name";
+  return manifest;
+}
+
+GURL CreateDefaultManifestURL() {
+  return GURL{"http://defaul-non-empty-url.com/manifest.json"};
+}
+
+std::unique_ptr<WebAppInstallInfo> CreateWebAppInstallInfo(
+    GURL start_url,
+    base::StringPiece manifest_id) {
+  WebAppInstallInfo install_info;
+  install_info.start_url = start_url;
+  install_info.manifest_id = std::string{manifest_id};
+
+  return std::make_unique<WebAppInstallInfo>(std::move(install_info));
+}
+
+SkBitmap CreateIcon() {
+  SkBitmap bitmap;
+  bitmap.allocN32Pixels(20, 20);
+  bitmap.eraseColor(SK_ColorMAGENTA);
+  return bitmap;
+}
+
+std::unique_ptr<WebAppInstallInfo> CreateDefaultWebAppInstallInfo() {
+  return CreateWebAppInstallInfo(
+      /*start_url=*/GURL{"http://test-start-url.com"},
+      /*manifest_id=*/"test manifest id");
+}
+
+std::unique_ptr<FakeDataRetriever> CreateDefaultDataRetriever() {
+  std::unique_ptr<FakeDataRetriever> fake_data_retriever =
+      std::make_unique<FakeDataRetriever>();
+
+  fake_data_retriever->SetRendererWebAppInstallInfo(
+      CreateDefaultWebAppInstallInfo());
+
+  fake_data_retriever->SetManifest(
+      /*manifest=*/CreateDefaultManifest(), /*is_installable=*/true,
+      /*manifest_url=*/CreateDefaultManifestURL());
+
+  fake_data_retriever->SetIconsDownloadedResult(
+      IconsDownloadedResult::kCompleted);
+  fake_data_retriever->SetIcons(std::map<GURL, std::vector<SkBitmap>>{
+      {GURL{"http://test-icon-url.com/icon.png"}, std::vector{CreateIcon()}},
+  });
+  constexpr int kSuccessHttpStatusCode = 200;
+  fake_data_retriever->SetDownloadedIconsHttpResults(std::map<GURL, int>{
+      {GURL{"http://test-icon-url.com/icon.png"}, kSuccessHttpStatusCode},
+  });
+
+  return fake_data_retriever;
+}
 
 class InstallIsolatedAppCommandTest : public ::testing::Test {
  public:
@@ -43,6 +119,9 @@
     auto url_loader = std::make_unique<TestWebAppUrlLoader>();
     url_loader_ = url_loader.get();
     provider->GetCommandManager().SetUrlLoaderForTesting(std::move(url_loader));
+    auto install_finalizer = std::make_unique<FakeInstallFinalizer>();
+    install_finalizer_ = install_finalizer.get();
+    provider->SetInstallFinalizer(std::move(install_finalizer));
 
     test::AwaitStartWebAppProviderAndSubsystems(profile());
   }
@@ -54,8 +133,8 @@
   std::unique_ptr<InstallIsolatedAppCommand> CreateCommand(
       base::StringPiece url,
       base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback) {
-    return std::make_unique<InstallIsolatedAppCommand>(url, *url_loader_,
-                                                       std::move(callback));
+    return std::make_unique<InstallIsolatedAppCommand>(
+        url, *url_loader_, *install_finalizer_, std::move(callback));
   }
 
   void ScheduleCommand(std::unique_ptr<WebAppCommand> command) {
@@ -94,38 +173,21 @@
     return test_future.Get();
   }
 
-  static std::unique_ptr<FakeDataRetriever> CreateDefaultDataRetriever() {
-    std::unique_ptr<FakeDataRetriever> fake_data_retriever =
-        std::make_unique<FakeDataRetriever>();
-
-    fake_data_retriever->SetManifest(
-        /*manifest=*/CreateDefaultManifest(), /*is_installable=*/true,
-        /*manifest_url=*/CreateDefaultManifestURL());
-    return fake_data_retriever;
-  }
-
-  static blink::mojom::ManifestPtr CreateDefaultManifest() {
-    auto manifest = blink::mojom::Manifest::New();
-    manifest->start_url = GURL{"http://test.com/"},
-    manifest->scope = GURL{"http://test.com/scope"},
-    manifest->display = DisplayMode::kStandalone;
-    manifest->short_name = u"Manifest Name";
-    return manifest;
-  }
-
-  static GURL CreateDefaultManifestURL() {
-    return GURL{"http://defaul-non-empty-url.com/manifest.json"};
-  }
-
   TestingProfile* profile() const { return profile_.get(); }
 
+  FakeInstallFinalizer& install_finalizer() {
+    DCHECK(install_finalizer_ != nullptr);
+    return *install_finalizer_;
+  }
+
  private:
   // Task environment allow to |base::OnceCallback| work in unit test.
   //
   // See details in //docs/threading_and_tasks_testing.md.
   content::BrowserTaskEnvironment browser_task_environment_;
 
-  base::raw_ptr<TestWebAppUrlLoader> url_loader_ = nullptr;
+  raw_ptr<TestWebAppUrlLoader> url_loader_ = nullptr;
+  raw_ptr<FakeInstallFinalizer> install_finalizer_ = nullptr;
 
   std::unique_ptr<TestingProfile> profile_ = []() {
     TestingProfile::Builder builder;
@@ -143,7 +205,7 @@
                             result_listener);
 }
 
-TEST_F(InstallIsolatedAppCommandTest, StartCanBeStartedSuccesfully) {
+TEST_F(InstallIsolatedAppCommandTest, CommandCanBeExecutedSuccesfully) {
   SetPrepareForLoadResultLoaded();
 
   ExpectLoadedForURL("http://test-url-example.com");
@@ -196,14 +258,64 @@
   ExpectLoadedForURL("http://test-url-example.com");
 
   std::unique_ptr<FakeDataRetriever> fake_data_retriever =
-      std::make_unique<FakeDataRetriever>();
-  fake_data_retriever->SetManifest(
-      /*manifest=*/CreateDefaultManifest(), /*is_installable=*/true,
-      /*manifest_url=*/CreateDefaultManifestURL());
+      CreateDefaultDataRetriever();
+
+  fake_data_retriever->SetRendererWebAppInstallInfo(CreateWebAppInstallInfo(
+      /*start_url=*/GURL{"http://test-start-url.com"},
+      /*manifest_id=*/"test manifest id"));
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
               IsInstallationOk());
+
+  WebAppInstallInfo install_info = *install_finalizer().web_app_info();
+  EXPECT_THAT(install_info.manifest_id, Eq("test manifest id"));
+}
+
+TEST_F(InstallIsolatedAppCommandTest,
+       PassesWebAppInstallInfoFromDataRetrieverToInstallFinalizer) {
+  SetPrepareForLoadResultLoaded();
+
+  ExpectLoadedForURL("http://test-url-example.com");
+
+  std::unique_ptr<FakeDataRetriever> fake_data_retriever =
+      CreateDefaultDataRetriever();
+
+  fake_data_retriever->SetRendererWebAppInstallInfo(CreateWebAppInstallInfo(
+      /*start_url=*/GURL{"http://test-start-url.com"},
+      /*manifest_id=*/"different test manifest id"));
+
+  EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
+                             std::move(fake_data_retriever)),
+              IsInstallationOk());
+
+  EXPECT_THAT(install_finalizer().web_app_info(),
+              Pointee(Field(&WebAppInstallInfo::manifest_id,
+                            Eq("different test manifest id"))));
+
+  EXPECT_THAT(install_finalizer().finalize_options_list(),
+              ElementsAre(Field(
+                  &WebAppInstallFinalizer::FinalizeOptions::install_surface,
+                  Eq(webapps::WebappInstallSource::MANAGEMENT_API))));
+}
+
+TEST_F(InstallIsolatedAppCommandTest, FailsWhenGetWebAppInstallInfoFails) {
+  SetPrepareForLoadResultLoaded();
+
+  ExpectLoadedForURL("http://test-url-example.com");
+
+  std::unique_ptr<FakeDataRetriever> fake_data_retriever =
+      CreateDefaultDataRetriever();
+
+  // |nullptr| indicates an error during |GetWebAppInstallInfo|.
+  //
+  // See |web_app::WebAppDataRetriever::GetWebAppInstallInfoCallback|
+  // documentation.
+  fake_data_retriever->SetRendererWebAppInstallInfo(nullptr);
+
+  EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
+                             std::move(fake_data_retriever)),
+              Not(IsInstallationOk()));
 }
 
 TEST_F(InstallIsolatedAppCommandTest,
@@ -246,6 +358,37 @@
               Not(IsInstallationOk()));
 }
 
+// TODO(kuragin): Add icon downloading functionality and fix the test.
+TEST_F(InstallIsolatedAppCommandTest,
+       DISABLED_DownloadedIconsArePassedToInstallFinalizer) {
+  SetPrepareForLoadResultLoaded();
+
+  ExpectLoadedForURL("http://some-test-url.com");
+
+  std::unique_ptr<FakeDataRetriever> fake_data_retriever =
+      CreateDefaultDataRetriever();
+
+  fake_data_retriever->SetIconsDownloadedResult(
+      IconsDownloadedResult::kCompleted);
+  fake_data_retriever->SetIcons(std::map<GURL, std::vector<SkBitmap>>{
+      {GURL{"http://different-test-icon-url.com/icon.png"},
+       std::vector{CreateIcon()}},
+  });
+  constexpr int kSuccessHttpStatusCode = 200;
+  fake_data_retriever->SetDownloadedIconsHttpResults(std::map<GURL, int>{
+      {GURL{"http://different-test-icon-url.com/icon.png"},
+       kSuccessHttpStatusCode},
+  });
+
+  EXPECT_THAT(ExecuteCommand("http://some-test-url.com",
+                             std::move(fake_data_retriever)),
+              IsInstallationOk());
+
+  WebAppInstallInfo install_info = *install_finalizer().web_app_info();
+  EXPECT_THAT(install_info.icon_bitmaps.GetBitmapsForPurpose(IconPurpose::ANY),
+              UnorderedElementsAre(Pair(_, _)));
+}
+
 using InstallIsolatedAppCommandMetricsTest = InstallIsolatedAppCommandTest;
 
 TEST_F(InstallIsolatedAppCommandMetricsTest,
@@ -254,24 +397,24 @@
 
   ExpectLoadedForURL("http://test-url-example.com");
 
-  base::HistogramTester histogram_tester_;
+  base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
               IsInstallationOk());
 
-  EXPECT_THAT(histogram_tester_.GetAllSamples("WebApp.Install.Result"),
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               base::BucketsAre(base::Bucket(true, 1)));
 }
 
 TEST_F(InstallIsolatedAppCommandMetricsTest, ReportFailureWhenURLIsInvalid) {
   SetPrepareForLoadResultLoaded();
 
-  base::HistogramTester histogram_tester_;
+  base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("some definetely invalid url"),
               Not(IsInstallationOk()));
 
-  EXPECT_THAT(histogram_tester_.GetAllSamples("WebApp.Install.Result"),
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               base::BucketsAre(base::Bucket(false, 1)));
 }
 
@@ -280,12 +423,12 @@
 
   ExpectFailureForURL("http://test-url-example.com");
 
-  base::HistogramTester histogram_tester_;
+  base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
               Not(IsInstallationOk()));
 
-  EXPECT_THAT(histogram_tester_.GetAllSamples("WebApp.Install.Result"),
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               base::BucketsAre(base::Bucket(false, 1)));
 }
 
@@ -305,13 +448,13 @@
       /*manifest_url=*/
       GURL{"http://test-url-example.com/manifest.json"});
 
-  base::HistogramTester histogram_tester_;
+  base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
               Not(IsInstallationOk()));
 
-  EXPECT_THAT(histogram_tester_.GetAllSamples("WebApp.Install.Result"),
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               base::BucketsAre(base::Bucket(false, 1)));
 }
 
@@ -328,13 +471,38 @@
       /*is_installable=*/true,
       /*manifest_url=*/CreateDefaultManifestURL());
 
-  base::HistogramTester histogram_tester_;
+  base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
               Not(IsInstallationOk()));
 
-  EXPECT_THAT(histogram_tester_.GetAllSamples("WebApp.Install.Result"),
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
+              base::BucketsAre(base::Bucket(false, 1)));
+}
+
+TEST_F(InstallIsolatedAppCommandMetricsTest,
+       ReportsAnErrorWhenGetWebAppInstallInfoFails) {
+  SetPrepareForLoadResultLoaded();
+
+  ExpectLoadedForURL("http://test-url-example.com");
+
+  std::unique_ptr<FakeDataRetriever> fake_data_retriever =
+      CreateDefaultDataRetriever();
+
+  // |nullptr| indicates an error during |GetWebAppInstallInfo|.
+  //
+  // See |web_app::WebAppDataRetriever::GetWebAppInstallInfoCallback|
+  // documentation.
+  fake_data_retriever->SetRendererWebAppInstallInfo(nullptr);
+
+  base::HistogramTester histogram_tester;
+
+  EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
+                             std::move(fake_data_retriever)),
+              Not(IsInstallationOk()));
+
+  EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               base::BucketsAre(base::Bucket(false, 1)));
 }
 
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
index 4a6243b..3b7d29e 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
@@ -35,6 +35,7 @@
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/taskbar_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -555,13 +556,14 @@
   std::vector<base::FilePath> shortcut_paths =
       GetShortcutPaths(creation_locations);
 
-  bool pin_to_taskbar = creation_locations.in_quick_launch_bar &&
-                        base::win::CanPinShortcutToTaskbar();
+  bool pin_to_taskbar =
+      creation_locations.in_quick_launch_bar && CanPinShortcutToTaskbar();
 
   // Create/update the shortcut in the web app path for the "Pin To Taskbar"
-  // option in Win7. We use the web app path shortcut because we will overwrite
-  // it rather than appending unique numbers if the shortcut already exists.
-  // This prevents pinned apps from having unique numbers in their names.
+  // option in Win7 and Win10 versions that support pinning. We use the web app
+  // path shortcut because we will overwrite it rather than appending unique
+  // numbers if the shortcut already exists. This prevents pinned apps from
+  // having unique numbers in their names.
   if (pin_to_taskbar)
     shortcut_paths.push_back(web_app_path);
 
@@ -581,7 +583,7 @@
     // in the application name.
     base::FilePath shortcut_to_pin =
         web_app_path.Append(file_name).AddExtension(installer::kLnkExt);
-    if (!base::win::PinShortcutToTaskbar(shortcut_to_pin))
+    if (!PinShortcutToTaskbar(shortcut_to_pin))
       return false;
   }
 
@@ -737,10 +739,9 @@
        ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_APPS_DIR,
        testing_shortcuts ? testing_shortcuts->application_menu.GetPath()
                          : base::FilePath()},
-      {// For Windows 7 and 8, |in_quick_launch_bar| indicates that we are
-       // pinning to taskbar. This needs to be handled by callers.
-       creation_locations.in_quick_launch_bar &&
-           base::win::CanPinShortcutToTaskbar(),
+      {// For some versions of Windows, `in_quick_launch_bar` indicates that we
+       // are pinning to taskbar. This needs to be handled by callers.
+       creation_locations.in_quick_launch_bar && CanPinShortcutToTaskbar(),
        ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
        testing_shortcuts ? testing_shortcuts->quick_launch.GetPath()
                          : base::FilePath()},
diff --git a/chrome/browser/web_applications/web_app_icon_generator.cc b/chrome/browser/web_applications/web_app_icon_generator.cc
index 03d34cd..75cc082 100644
--- a/chrome/browser/web_applications/web_app_icon_generator.cc
+++ b/chrome/browser/web_applications/web_app_icon_generator.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/i18n/case_conversion.h"
+#include "base/strings/utf_string_conversion_utils.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -36,7 +37,7 @@
 // |icon_letter| into a rounded background of |color|.
 class GeneratedIconImageSource : public gfx::CanvasImageSource {
  public:
-  explicit GeneratedIconImageSource(char16_t icon_letter,
+  explicit GeneratedIconImageSource(char32_t icon_letter,
                                     SkColor color,
                                     SquareSizePx output_size)
       : gfx::CanvasImageSource(gfx::Size(output_size, output_size)),
@@ -77,13 +78,13 @@
     // The text rect's size needs to be odd to center the text correctly.
     gfx::Rect text_rect(icon_inset, icon_inset, icon_size + 1, icon_size + 1);
     canvas->DrawStringRectWithFlags(
-        std::u16string(1, icon_letter_),
+        IconLetterToString(icon_letter_),
         gfx::FontList(gfx::Font(font_name, font_size)),
         color_utils::GetColorWithMaxContrast(color_), text_rect,
         gfx::Canvas::TEXT_ALIGN_CENTER);
   }
 
-  char16_t icon_letter_;
+  char32_t icon_letter_;
 
   SkColor color_;
 
@@ -97,7 +98,7 @@
 void GenerateIcon(SizeToBitmap* bitmaps,
                   SquareSizePx output_size,
                   SkColor color,
-                  char16_t icon_letter) {
+                  char32_t icon_letter) {
   // Do nothing if there is already an icon of |output_size|.
   if (bitmaps->count(output_size))
     return;
@@ -106,7 +107,7 @@
 }
 
 void GenerateIcons(const std::set<SquareSizePx>& generate_sizes,
-                   char16_t icon_letter,
+                   char32_t icon_letter,
                    SkColor generated_icon_color,
                    SizeToBitmap* bitmap_map) {
   // If no color has been specified, use a dark gray so it will stand out on the
@@ -118,6 +119,19 @@
     GenerateIcon(bitmap_map, size, generated_icon_color, icon_letter);
 }
 
+// Gets the first code point of a string.
+char32_t FirstCodepoint(const std::u16string& str) {
+  DCHECK(!str.empty());
+  size_t index = 0;
+  base_icu::UChar32 cp;
+  if (!base::ReadUnicodeCharacter(str.data(), str.size(), &index, &cp)) {
+    // U+FFFD REPLACEMENT CHARACTER
+    return 0xfffd;
+  }
+
+  return cp;
+}
+
 }  // namespace
 
 std::set<SquareSizePx> SizesToGenerate() {
@@ -164,7 +178,7 @@
 
 SkBitmap GenerateBitmap(SquareSizePx output_size,
                         SkColor color,
-                        char16_t icon_letter) {
+                        char32_t icon_letter) {
   gfx::ImageSkia icon_image(std::make_unique<GeneratedIconImageSource>(
                                 icon_letter, color, output_size),
                             gfx::Size(output_size, output_size));
@@ -176,7 +190,7 @@
   return dst;
 }
 
-char16_t GenerateIconLetterFromUrl(const GURL& app_url) {
+char32_t GenerateIconLetterFromUrl(const GURL& app_url) {
   std::string app_url_part = " ";
   const std::string domain_and_registry =
       net::registry_controlled_domains::GetDomainAndRegistry(
@@ -193,19 +207,24 @@
   const std::u16string string_for_display =
       url_formatter::IDNToUnicode(app_url_part);
 
-  char16_t icon_letter = base::i18n::ToUpper(string_for_display)[0];
-  return icon_letter;
+  return FirstCodepoint(base::i18n::ToUpper(string_for_display));
 }
 
-char16_t GenerateIconLetterFromAppName(const std::u16string& app_name) {
+char32_t GenerateIconLetterFromAppName(const std::u16string& app_name) {
   CHECK(!app_name.empty());
-  return base::i18n::ToUpper(app_name)[0];
+  return FirstCodepoint(base::i18n::ToUpper(app_name));
+}
+
+std::u16string IconLetterToString(char32_t cp) {
+  std::u16string str;
+  base::WriteUnicodeCharacter(cp, &str);
+  return str;
 }
 
 SizeToBitmap ResizeIconsAndGenerateMissing(
     const std::vector<SkBitmap>& icons,
     const std::set<SquareSizePx>& sizes_to_generate,
-    char16_t icon_letter,
+    char32_t icon_letter,
     SkColor* generated_icon_color,
     bool* is_generated_icon) {
   DCHECK(generated_icon_color);
@@ -245,7 +264,7 @@
 SizeToBitmap GenerateIcons(const std::string& app_name,
                            SkColor background_icon_color) {
   const std::u16string app_name_utf16 = base::UTF8ToUTF16(app_name);
-  const char16_t icon_letter = GenerateIconLetterFromAppName(app_name_utf16);
+  const char32_t icon_letter = GenerateIconLetterFromAppName(app_name_utf16);
 
   SizeToBitmap icons;
   for (SquareSizePx size : SizesToGenerate()) {
diff --git a/chrome/browser/web_applications/web_app_icon_generator.h b/chrome/browser/web_applications/web_app_icon_generator.h
index cb01d10..0524eef 100644
--- a/chrome/browser/web_applications/web_app_icon_generator.h
+++ b/chrome/browser/web_applications/web_app_icon_generator.h
@@ -65,15 +65,21 @@
 // |icon_letter| into a rounded background of |color|.
 SkBitmap GenerateBitmap(SquareSizePx output_size,
                         SkColor color,
-                        char16_t icon_letter);
+                        char32_t icon_letter);
 
 // Returns the first letter from |app_url| that will be painted on the generated
 // icon.
-char16_t GenerateIconLetterFromUrl(const GURL& app_url);
+char32_t GenerateIconLetterFromUrl(const GURL& app_url);
 
 // Returns the first letter from |app_name| that will be painted on the
 // generated icon.
-char16_t GenerateIconLetterFromAppName(const std::u16string& app_name);
+char32_t GenerateIconLetterFromAppName(const std::u16string& app_name);
+
+// Converts a codepoint (intended to be the first letter of an app name or URL)
+// to a UTF-16 string.
+//
+// Public for testing.
+std::u16string IconLetterToString(char32_t cp);
 
 // Resize icons to the accepted sizes, and generate any that are missing.
 // Note that |icon_letter| is the first letter of app name if available
@@ -84,7 +90,7 @@
 SizeToBitmap ResizeIconsAndGenerateMissing(
     const std::vector<SkBitmap>& icons,
     const std::set<SquareSizePx>& sizes_to_generate,
-    char16_t icon_letter,
+    char32_t icon_letter,
     SkColor* generated_icon_color,
     bool* is_generated_icon);
 
diff --git a/chrome/browser/web_applications/web_app_icon_generator_unittest.cc b/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
index 77ee106..27b4d77 100644
--- a/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
+++ b/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
@@ -354,22 +354,56 @@
 
 TEST_F(WebAppIconGeneratorTest, GenerateIconLetterFromUrl) {
   // ASCII:
-  EXPECT_EQ('E', GenerateIconLetterFromUrl(GURL("http://example.com")));
+  EXPECT_EQ((char32_t)'E',
+            GenerateIconLetterFromUrl(GURL("http://example.com")));
   // Cyrillic capital letter ZHE for something like https://zhuk.rf:
-  EXPECT_EQ(0x0416,
+  EXPECT_EQ(0x0416U,
             GenerateIconLetterFromUrl(GURL("https://xn--f1ai0a.xn--p1ai/")));
   // Arabic:
-  EXPECT_EQ(0x0645,
+  EXPECT_EQ(0x0645U,
             GenerateIconLetterFromUrl(GURL("http://xn--mgbh0fb.example/")));
+  // UTF-16 surrogate code units.
+  // "𨭎𨥫𨋍" (U+28B4E, U+2896B, U+282CD)
+  // (nonsensical sequence of non-BMP Chinese characters, IDNA-encoded)
+  EXPECT_EQ(0x28b4eU,
+            GenerateIconLetterFromUrl(GURL("http://xn--8h8k10hnsb.example/")));
+  // "🌏👍" (U+1F30F, U+1F44D)
+  // (sequence of non-BMP emoji characters, IDNA-encoded)
+  // Emoji are not allowed in IDNA domains, so the first character of this
+  // domain is simply 'X'.
+  EXPECT_EQ((char32_t)'X',
+            GenerateIconLetterFromUrl(GURL("http://xn--vg8h2t.example/")));
 }
 
 TEST_F(WebAppIconGeneratorTest, GenerateIconLetterFromAppName) {
   // ASCII Encoding
-  EXPECT_EQ('T', GenerateIconLetterFromAppName(u"test app name"));
-  EXPECT_EQ('T', GenerateIconLetterFromAppName(u"Test app name"));
-  // UTF16 encoding:
+  EXPECT_EQ((char32_t)'T', GenerateIconLetterFromAppName(u"test app name"));
+  EXPECT_EQ((char32_t)'T', GenerateIconLetterFromAppName(u"Test app name"));
+  // UTF-16 encoding (single code units):
+  // "имя" (U+0438, U+043C, U+044F)
   const char16_t russian_name[] = {0x0438, 0x043c, 0x044f, 0x0};
-  EXPECT_EQ(0x0418, GenerateIconLetterFromAppName(russian_name));
+  EXPECT_EQ(0x0418U, GenerateIconLetterFromAppName(russian_name));
+  // UTF-16 surrogate code units.
+  // "𨭎𨥫𨋍" (U+28B4E, U+2896B, U+282CD)
+  // (nonsensical sequence of non-BMP Chinese characters, UTF-16-encoded)
+  const char16_t chinese_name[] = {0xd862, 0xdf4e, 0xd862, 0xdd6b,
+                                   0xd860, 0xdecd, 0x0};
+  EXPECT_EQ(0x28b4eU, GenerateIconLetterFromAppName(chinese_name));
+  // "🌏👍" (U+1F30F, U+1F44D)
+  // (sequence of non-BMP emoji characters, UTF-16-encoded)
+  const char16_t emoji_name[] = {0xd83c, 0xdf0f, 0xd83d, 0xdc4d, 0x0};
+  EXPECT_EQ(0x1f30fU, GenerateIconLetterFromAppName(emoji_name));
+}
+
+TEST_F(WebAppIconGeneratorTest, IconLetterToString) {
+  // ASCII character
+  EXPECT_EQ(u"T", IconLetterToString('T'));
+  // BMP character 'И' (U+0418)
+  EXPECT_EQ(std::u16string({0x0418}), IconLetterToString(0x0418));
+  // Non-BMP character '𨭎' (U+28B4E)
+  EXPECT_EQ(std::u16string({0xd862, 0xdf4e}), IconLetterToString(0x28b4e));
+  // Non-BMP character '🌏' (U+1F30F)
+  EXPECT_EQ(std::u16string({0xd83c, 0xdf0f}), IconLetterToString(0x1f30f));
 }
 
 TEST_F(WebAppIconGeneratorTest, GenerateIcons) {
diff --git a/chrome/browser/web_applications/web_app_install_utils.cc b/chrome/browser/web_applications/web_app_install_utils.cc
index df8afcd..a7fc98a 100644
--- a/chrome/browser/web_applications/web_app_install_utils.cc
+++ b/chrome/browser/web_applications/web_app_install_utils.cc
@@ -683,7 +683,7 @@
       web_app_info->icon_bitmaps.monochrome[bitmap.width()] = std::move(bitmap);
   }
 
-  char16_t icon_letter =
+  char32_t icon_letter =
       web_app_info->title.empty()
           ? GenerateIconLetterFromUrl(web_app_info->start_url)
           : GenerateIconLetterFromAppName(web_app_info->title);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 122f3aa..54316dd1 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1659549585-998f2a348263bf80f8e6b9bf998d9380e9afb578.profdata
+chrome-linux-main-1659571197-4c81cce6700087fd9957c31c9c8bcda7bde3719f.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index ddb13b6..58696395 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1659505904-89e971e3c599a012db0555602c13bc00bddf6a33.profdata
+chrome-mac-arm-main-1659571197-d740b382a0ffe61c54eafa5419ba43f39463fb66.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 1fce8da..80f5731 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1659505904-90cd344349313ba7965827550accab4af50c8300.profdata
+chrome-mac-main-1659571197-9514832ba7704be70bbaad14bf8f74381c5094a0.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 9b30a0d..6ea199e 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1659517197-9ea12a2575a72436c0ac57d2fcb150844b7cc228.profdata
+chrome-win32-main-1659566430-fe05d2d9bbf12f3e80a465121005d66334cc612f.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 60f5b2d..730edcd 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1659517197-7cf67731ce3ab090e62d83e3d26d824f1f46d75f.profdata
+chrome-win64-main-1659571197-6bc81f1865e1c69e461a140d681e26dc3e3ac1c1.profdata
diff --git a/chrome/common/extensions/manifest_handlers/theme_handler.cc b/chrome/common/extensions/manifest_handlers/theme_handler.cc
index 6573b5c3..1e7acfe2 100644
--- a/chrome/common/extensions/manifest_handlers/theme_handler.cc
+++ b/chrome/common/extensions/manifest_handlers/theme_handler.cc
@@ -51,7 +51,8 @@
         return false;
       }
     }
-    theme_info->theme_images_.reset(images_value->DeepCopy());
+    theme_info->theme_images_ = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(images_value->Clone()));
   }
   return true;
 }
@@ -127,7 +128,8 @@
     }
   }
 
-  theme_info->theme_tints_.reset(tints_value->DeepCopy());
+  theme_info->theme_tints_ = base::DictionaryValue::From(
+      base::Value::ToUniquePtrValue(tints_value->Clone()));
   return true;
 }
 
@@ -137,8 +139,8 @@
   const base::DictionaryValue* display_properties_value = NULL;
   if (theme_value->GetDictionary(keys::kThemeDisplayProperties,
                                  &display_properties_value)) {
-    theme_info->theme_display_properties_.reset(
-        display_properties_value->DeepCopy());
+    theme_info->theme_display_properties_ = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(display_properties_value->Clone()));
   }
   return true;
 }
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index 1356261..34fdd2cc 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -21,12 +21,14 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
+#include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "base/win/shortcut.h"
+#include "base/win/windows_version.h"
 #include "chrome/install_static/install_details.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome/installer/setup/install_params.h"
@@ -47,9 +49,11 @@
 #include "chrome/installer/util/installation_state.h"
 #include "chrome/installer/util/installer_util_strings.h"
 #include "chrome/installer/util/l10n_string_util.h"
+#include "chrome/installer/util/taskbar_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "chrome/installer/util/work_item.h"
 #include "chrome/installer/util/work_item_list.h"
+#include "components/version_info/channel.h"
 
 namespace installer {
 
@@ -108,7 +112,7 @@
   if (properties.has_arguments())
     message.append(base::WideToUTF8(properties.arguments));
 
-  if (properties.pin_to_taskbar && base::win::CanPinShortcutToTaskbar())
+  if (properties.pin_to_taskbar && CanPinShortcutToTaskbar())
     message.append(" and pinning to the taskbar");
 
   message.push_back('.');
@@ -290,6 +294,26 @@
   return true;
 }
 
+// This function will control the rollout of the installer pinning Chrome to the
+// taskbar on Win10+, for Beta and Stable channels.
+bool ShouldPinChromeToTaskbar() {
+  if (base::win::GetVersion() < base::win::Version::WIN10)
+    return true;
+  switch (install_static::GetChromeChannel()) {
+    case version_info::Channel::BETA: {
+      // Increase kBetaRolloutPercentage to roll out to beta channel.
+      constexpr int kBetaRolloutPercentage = 0;
+      return base::RandInt(0, 99) < kBetaRolloutPercentage;
+    }
+    case version_info::Channel::STABLE: {
+      constexpr int kStableRolloutPercentage = 0;
+      return base::RandInt(0, 99) < kStableRolloutPercentage;
+    }
+    default:
+      return false;
+  }
+}
+
 }  // namespace
 
 bool CreateVisualElementsManifest(const base::FilePath& src_path,
@@ -384,7 +408,12 @@
   if (shortcut_operation == ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS ||
       shortcut_operation ==
           ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL) {
-    start_menu_properties.set_pin_to_taskbar(!do_not_create_taskbar_shortcut);
+    // ShouldPinChromeToTaskbar will control the rollout of installer pinning to
+    // the taskbar, for Win10+ beta and stable channels.
+    bool pin_to_taskbar =
+        !do_not_create_taskbar_shortcut && ShouldPinChromeToTaskbar();
+
+    start_menu_properties.set_pin_to_taskbar(pin_to_taskbar);
   }
 
   const CLSID toast_activator_clsid = install_static::GetToastActivatorClsid();
diff --git a/chrome/installer/setup/install_unittest.cc b/chrome/installer/setup/install_unittest.cc
index fbf54c9..e897e5944 100644
--- a/chrome/installer/setup/install_unittest.cc
+++ b/chrome/installer/setup/install_unittest.cc
@@ -36,6 +36,7 @@
 #include "chrome/installer/util/installer_util_strings.h"
 #include "chrome/installer/util/l10n_string_util.h"
 #include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/taskbar_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -267,10 +268,10 @@
   void TearDown() override {
     // Try to unpin potentially pinned shortcuts (although pinning isn't tested,
     // the call itself might still have pinned the Start Menu shortcuts).
-    base::win::UnpinShortcutFromTaskbar(user_start_menu_shortcut_);
-    base::win::UnpinShortcutFromTaskbar(user_start_menu_subdir_shortcut_);
-    base::win::UnpinShortcutFromTaskbar(system_start_menu_shortcut_);
-    base::win::UnpinShortcutFromTaskbar(system_start_menu_subdir_shortcut_);
+    UnpinShortcutFromTaskbar(user_start_menu_shortcut_);
+    UnpinShortcutFromTaskbar(user_start_menu_subdir_shortcut_);
+    UnpinShortcutFromTaskbar(system_start_menu_shortcut_);
+    UnpinShortcutFromTaskbar(system_start_menu_subdir_shortcut_);
   }
 
   installer::InitialPreferences* GetFakeMasterPrefs(
diff --git a/chrome/installer/util/BUILD.gn b/chrome/installer/util/BUILD.gn
index e523782..881de469 100644
--- a/chrome/installer/util/BUILD.gn
+++ b/chrome/installer/util/BUILD.gn
@@ -164,6 +164,8 @@
       "scoped_user_protocol_entry.h",
       "shell_util.cc",
       "shell_util.h",
+      "taskbar_util.cc",
+      "taskbar_util.h",
     ]
 
     public_deps += [
diff --git a/chrome/installer/util/OWNERS b/chrome/installer/util/OWNERS
index 90977f8..f25cab8 100644
--- a/chrome/installer/util/OWNERS
+++ b/chrome/installer/util/OWNERS
@@ -1,2 +1,3 @@
 per-file shell_util*=davidbienvenu@chromium.org
 per-file shell_util*=jessemckenna@google.com
+per-file tasbar_util*=davidbienvenu@chromium.org
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 9b8ac75..3b3d161 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -67,6 +67,7 @@
 #include "chrome/installer/util/registry_entry.h"
 #include "chrome/installer/util/registry_util.h"
 #include "chrome/installer/util/scoped_user_protocol_entry.h"
+#include "chrome/installer/util/taskbar_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "chrome/installer/util/work_item.h"
 #include "components/base32/base32.h"
@@ -93,8 +94,6 @@
   CONFIRM_SHELL_REGISTRATION_IN_HKLM,
 };
 
-enum class PinnedListModifyCaller { kExplorer = 4 };
-
 const wchar_t kReinstallCommand[] = L"ReinstallCommand";
 
 constexpr wchar_t kRegHash[] = L"Hash";
@@ -107,34 +106,6 @@
 
 const wchar_t kFileExtensions[] = L"FileExtensions";
 
-constexpr GUID CLSID_TaskbandPin = {
-    0x90aa3a4e,
-    0x1cba,
-    0x4233,
-    {0xb8, 0xbb, 0x53, 0x57, 0x73, 0xd4, 0x84, 0x49}};
-
-// Undocumented COM interface for manipulating taskbar pinned list.
-class __declspec(uuid("0DD79AE2-D156-45D4-9EEB-3B549769E940")) IPinnedList3
-    : public IUnknown {
- public:
-  virtual HRESULT STDMETHODCALLTYPE EnumObjects() = 0;
-  virtual HRESULT STDMETHODCALLTYPE GetPinnableInfo() = 0;
-  virtual HRESULT STDMETHODCALLTYPE IsPinnable() = 0;
-  virtual HRESULT STDMETHODCALLTYPE Resolve() = 0;
-  virtual HRESULT STDMETHODCALLTYPE LegacyModify() = 0;
-  virtual HRESULT STDMETHODCALLTYPE GetChangeCount() = 0;
-  virtual HRESULT STDMETHODCALLTYPE IsPinned(PCIDLIST_ABSOLUTE) = 0;
-  virtual HRESULT STDMETHODCALLTYPE GetPinnedItem() = 0;
-  virtual HRESULT STDMETHODCALLTYPE GetAppIDForPinnedItem() = 0;
-  virtual HRESULT STDMETHODCALLTYPE ItemChangeNotify() = 0;
-  virtual HRESULT STDMETHODCALLTYPE UpdateForRemovedItemsAsNecessary() = 0;
-  virtual HRESULT STDMETHODCALLTYPE PinShellLink() = 0;
-  virtual HRESULT STDMETHODCALLTYPE GetPinnedItemForAppID() = 0;
-  virtual HRESULT STDMETHODCALLTYPE Modify(PCIDLIST_ABSOLUTE unpin,
-                                           PCIDLIST_ABSOLUTE pin,
-                                           PinnedListModifyCaller caller) = 0;
-};
-
 // Returns the current (or installed) browser's ProgId (e.g.
 // "ChromeHTML|suffix|").
 // |suffix| can be the empty string.
@@ -1295,7 +1266,7 @@
 
 bool ShortcutOpUnpinFromTaskbar(const base::FilePath& shortcut_path) {
   VLOG(1) << "Trying to unpin from taskbar " << shortcut_path.value();
-  if (!base::win::UnpinShortcutFromTaskbar(shortcut_path)) {
+  if (!UnpinShortcutFromTaskbar(shortcut_path)) {
     VLOG(1) << shortcut_path.value()
             << " wasn't pinned to taskbar (or the unpin failed).";
     // No error, since shortcut might not be pinned.
@@ -1876,36 +1847,6 @@
   return false;
 }
 
-// ScopedPIDLFromPath class, and the idea of using IPinnedList3::Modify,
-// are thanks to Gee Law <https://geelaw.blog/entries/msedge-pins/>
-class ScopedPIDLFromPath {
- public:
-  explicit ScopedPIDLFromPath(PCWSTR path)
-      : p_id_list_(ILCreateFromPath(path)) {}
-  ~ScopedPIDLFromPath() {
-    if (p_id_list_)
-      ILFree(p_id_list_);
-  }
-  PIDLIST_ABSOLUTE Get() const { return p_id_list_; }
-
- private:
-  PIDLIST_ABSOLUTE const p_id_list_;
-};
-
-// Returns the taskbar pinned list if successful, an empty ComPtr otherwise.
-Microsoft::WRL::ComPtr<IPinnedList3> GetTaskbarPinnedList() {
-  if (base::win::GetVersion() < base::win::Version::WIN10_RS5)
-    return nullptr;
-
-  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list;
-  if (FAILED(CoCreateInstance(CLSID_TaskbandPin, nullptr, CLSCTX_INPROC_SERVER,
-                              IID_PPV_ARGS(&pinned_list)))) {
-    return nullptr;
-  }
-
-  return pinned_list;
-}
-
 }  // namespace
 
 const wchar_t* ShellUtil::kRegAppProtocolHandlers = L"\\AppProtocolHandlers";
@@ -2183,8 +2124,8 @@
   }
 
   if (shortcut_operation == base::win::ShortcutOperation::kCreateAlways &&
-      properties.pin_to_taskbar && base::win::CanPinShortcutToTaskbar()) {
-    bool pinned = base::win::PinShortcutToTaskbar(shortcut_path);
+      properties.pin_to_taskbar && CanPinShortcutToTaskbar()) {
+    bool pinned = PinShortcutToTaskbar(shortcut_path);
     LOG_IF(ERROR, !pinned) << "Failed to pin to taskbar "
                            << shortcut_path.value();
   }
@@ -3231,30 +3172,6 @@
 }
 
 // static
-bool ShellUtil::PinShortcut(const base::FilePath& shortcut) {
-  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list = GetTaskbarPinnedList();
-  if (!pinned_list)
-    return false;
-
-  ScopedPIDLFromPath item_id_list(shortcut.value().data());
-  HRESULT hr = pinned_list->Modify(nullptr, item_id_list.Get(),
-                                   PinnedListModifyCaller::kExplorer);
-  return SUCCEEDED(hr);
-}
-
-// static
-absl::optional<bool> ShellUtil::IsShortcutPinned(
-    const base::FilePath& shortcut) {
-  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list = GetTaskbarPinnedList();
-  if (!pinned_list.Get())
-    return absl::nullopt;
-
-  ScopedPIDLFromPath item_id_list(shortcut.value().data());
-  HRESULT hr = pinned_list->IsPinned(item_id_list.Get());
-  // S_OK means `shortcut` is pinned, S_FALSE mean it's not pinned.
-  return SUCCEEDED(hr) ? absl::optional<bool>(hr == S_OK) : absl::nullopt;
-}
-
 std::array<uint32_t, 4> ShellUtil::ComputeHashForTesting(
     base::span<const uint8_t> input) {
   return ComputeHash(input);
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 916cd11..772fb3a 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -869,16 +869,6 @@
       const std::vector<std::unique_ptr<RegistryEntry>>& entries,
       bool best_effort_no_rollback = false);
 
-  // Use IPinnedList3 to pin shortcut to taskbar on WIN10_RS5 and above.
-  // Returns true if pinning was successful.
-  static bool PinShortcut(const base::FilePath& shortcut);
-
-  // Returns true if `shortcut` is pinned, false if not, and nullopt if
-  // IPinnedList3 is not supported (e.g., pre WIN10_RS5). Do not to call
-  // this on the Browser UI thread since it calls CoCreateInstance, which can
-  // cause jank.
-  static absl::optional<bool> IsShortcutPinned(const base::FilePath& shortcut);
-
   static std::array<uint32_t, 4> ComputeHashForTesting(
       base::span<const uint8_t> input);
 
diff --git a/chrome/installer/util/taskbar_util.cc b/chrome/installer/util/taskbar_util.cc
new file mode 100644
index 0000000..bd6983d
--- /dev/null
+++ b/chrome/installer/util/taskbar_util.cc
@@ -0,0 +1,133 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/installer/util/taskbar_util.h"
+
+#include <objbase.h>
+#include <shellapi.h>
+#include <shlobj.h>
+#include <wrl/client.h>
+
+#include "base/files/file_path.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "base/win/windows_version.h"
+
+namespace {
+
+enum class PinnedListModifyCaller { kExplorer = 4 };
+
+constexpr GUID CLSID_TaskbandPin = {
+    0x90aa3a4e,
+    0x1cba,
+    0x4233,
+    {0xb8, 0xbb, 0x53, 0x57, 0x73, 0xd4, 0x84, 0x49}};
+
+// Undocumented COM interface for manipulating taskbar pinned list.
+class __declspec(uuid("0DD79AE2-D156-45D4-9EEB-3B549769E940")) IPinnedList3
+    : public IUnknown {
+ public:
+  virtual HRESULT STDMETHODCALLTYPE EnumObjects() = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPinnableInfo() = 0;
+  virtual HRESULT STDMETHODCALLTYPE IsPinnable() = 0;
+  virtual HRESULT STDMETHODCALLTYPE Resolve() = 0;
+  virtual HRESULT STDMETHODCALLTYPE LegacyModify() = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetChangeCount() = 0;
+  virtual HRESULT STDMETHODCALLTYPE IsPinned(PCIDLIST_ABSOLUTE) = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPinnedItem() = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetAppIDForPinnedItem() = 0;
+  virtual HRESULT STDMETHODCALLTYPE ItemChangeNotify() = 0;
+  virtual HRESULT STDMETHODCALLTYPE UpdateForRemovedItemsAsNecessary() = 0;
+  virtual HRESULT STDMETHODCALLTYPE PinShellLink() = 0;
+  virtual HRESULT STDMETHODCALLTYPE GetPinnedItemForAppID() = 0;
+  virtual HRESULT STDMETHODCALLTYPE Modify(PCIDLIST_ABSOLUTE unpin,
+                                           PCIDLIST_ABSOLUTE pin,
+                                           PinnedListModifyCaller caller) = 0;
+};
+
+// ScopedPIDLFromPath class, and the idea of using IPinnedList3::Modify,
+// are thanks to Gee Law <https://geelaw.blog/entries/msedge-pins/>
+class ScopedPIDLFromPath {
+ public:
+  explicit ScopedPIDLFromPath(PCWSTR path)
+      : p_id_list_(ILCreateFromPath(path)) {}
+  ~ScopedPIDLFromPath() {
+    if (p_id_list_)
+      ILFree(p_id_list_);
+  }
+  PIDLIST_ABSOLUTE Get() const { return p_id_list_; }
+
+ private:
+  PIDLIST_ABSOLUTE const p_id_list_;
+};
+
+// Returns the taskbar pinned list if successful, an empty ComPtr otherwise.
+Microsoft::WRL::ComPtr<IPinnedList3> GetTaskbarPinnedList() {
+  if (base::win::GetVersion() < base::win::Version::WIN10_RS5)
+    return nullptr;
+
+  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list;
+  if (FAILED(CoCreateInstance(CLSID_TaskbandPin, nullptr, CLSCTX_INPROC_SERVER,
+                              IID_PPV_ARGS(&pinned_list)))) {
+    return nullptr;
+  }
+
+  return pinned_list;
+}
+
+// Use IPinnedList3 to pin shortcut to taskbar on WIN10_RS5 and above.
+// Returns true if pinning was successful.
+// static
+bool PinShortcutWithIPinnedList3(const base::FilePath& shortcut) {
+  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list = GetTaskbarPinnedList();
+  if (!pinned_list)
+    return false;
+
+  ScopedPIDLFromPath item_id_list(shortcut.value().data());
+  HRESULT hr = pinned_list->Modify(nullptr, item_id_list.Get(),
+                                   PinnedListModifyCaller::kExplorer);
+  return SUCCEEDED(hr);
+}
+
+}  // namespace
+
+bool CanPinShortcutToTaskbar() {
+  // "Pin to taskbar" stopped being supported in Windows 10, but WIN10_RS5 has
+  // some undocumented interfaces to do pinning.
+  const auto version = base::win::GetVersion();
+  return version < base::win::Version::WIN10 ||
+         version >= base::win::Version::WIN10_RS5;
+}
+
+bool PinShortcutToTaskbar(const base::FilePath& shortcut) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  DCHECK(CanPinShortcutToTaskbar());
+  if (base::win::GetVersion() >= base::win::Version::WIN10_RS5)
+    return PinShortcutWithIPinnedList3(shortcut);
+
+  intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
+      nullptr, L"taskbarpin", shortcut.value().c_str(), nullptr, nullptr, 0));
+  return result > 32;
+}
+
+bool UnpinShortcutFromTaskbar(const base::FilePath& shortcut) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+
+  intptr_t result = reinterpret_cast<intptr_t>(ShellExecute(
+      nullptr, L"taskbarunpin", shortcut.value().c_str(), nullptr, nullptr, 0));
+  return result > 32;
+}
+
+// static
+absl::optional<bool> IsShortcutPinnedToTaskbar(const base::FilePath& shortcut) {
+  Microsoft::WRL::ComPtr<IPinnedList3> pinned_list = GetTaskbarPinnedList();
+  if (!pinned_list.Get())
+    return absl::nullopt;
+
+  ScopedPIDLFromPath item_id_list(shortcut.value().data());
+  HRESULT hr = pinned_list->IsPinned(item_id_list.Get());
+  // S_OK means `shortcut` is pinned, S_FALSE mean it's not pinned.
+  return SUCCEEDED(hr) ? absl::optional<bool>(hr == S_OK) : absl::nullopt;
+}
diff --git a/chrome/installer/util/taskbar_util.h b/chrome/installer/util/taskbar_util.h
new file mode 100644
index 0000000..d342d480
--- /dev/null
+++ b/chrome/installer/util/taskbar_util.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Common Windows Taskbar manipulation functions that can be used by the Windows
+// installer as well as Chrome.
+
+#ifndef CHROME_INSTALLER_UTIL_TASKBAR_UTIL_H_
+#define CHROME_INSTALLER_UTIL_TASKBAR_UTIL_H_
+
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+// Pin to taskbar is supported on Windows 7, 8 and Win10RS5+. Returns
+// true on those platforms.
+bool CanPinShortcutToTaskbar();
+
+// Pins a shortcut to the taskbar on Windows 7, 8 and Win10RS5+ . `shortcut`
+// file must already exist and be a shortcut that points to an executable.The
+// app id of the shortcut is used to group windows and must be set correctly.
+bool PinShortcutToTaskbar(const base::FilePath& shortcut);
+
+// Unpins a shortcut from the Windows 7+ taskbar. `shortcut` must exist
+// and already be pinned to the taskbar. The app id of the shortcut is used as
+// the identifier for the taskbar item to remove and must be set correctly.
+bool UnpinShortcutFromTaskbar(const base::FilePath& shortcut);
+
+// Returns true if `shortcut` is pinned, false if not, and nullopt if
+// IPinnedList3 is not supported (e.g., pre WIN10_RS5). Do not to call
+// this on the Browser UI thread since it calls CoCreateInstance, which can
+// cause jank.
+absl::optional<bool> IsShortcutPinnedToTaskbar(const base::FilePath& shortcut);
+
+#endif  // CHROME_INSTALLER_UTIL_TASKBAR_UTIL_H_
diff --git a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
index fa53e3d..344421c3 100644
--- a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
+++ b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
@@ -8,6 +8,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/cart/commerce_hint_service.h"
+#include "chrome/browser/new_tab_page/new_tab_page_util.h"
 #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
 #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -40,10 +41,13 @@
 #include "chrome/browser/cart/cart_service.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/scoped_browser_locale.h"
 #include "components/commerce/core/proto/cart_db_content.pb.h"
 #include "components/session_proto_db/session_proto_db.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "components/variations/service/variations_service.h"
+#include "components/variations/variations_switches.h"
 #endif
 
 namespace {
@@ -184,7 +188,9 @@
   using XHREntry = ukm::builders::Shopping_WillSendRequest;
   using ExtractionEntry = ukm::builders::Shopping_CartExtraction;
 
-  CommerceHintAgentTest() {
+  CommerceHintAgentTest() = default;
+
+  void SetUpInProcessBrowserTestFixture() override {
     scoped_feature_list_.InitWithFeaturesAndParameters(
         {{
 #if !BUILDFLAG(IS_ANDROID)
@@ -1538,13 +1544,19 @@
 // TODO(crbug/1310497): This test is flaky on ChromeOS.
 class CommerceHintAgentFencedFrameTest : public CommerceHintAgentTest {
  public:
-  CommerceHintAgentFencedFrameTest() = default;
-  ~CommerceHintAgentFencedFrameTest() override = default;
-  CommerceHintAgentFencedFrameTest(const CommerceHintAgentFencedFrameTest&) =
-      delete;
+  CommerceHintAgentFencedFrameTest() {
+    scoped_feature_list_.InitWithFeatures(
+        {
+#if !BUILDFLAG(IS_ANDROID)
+          ntp_features::kNtpChromeCartModule
+#else
+          commerce::kCommerceHintAndroid
+#endif
+        },
+        {optimization_guide::features::kOptimizationHints});
+  }
 
-  CommerceHintAgentFencedFrameTest& operator=(
-      const CommerceHintAgentFencedFrameTest&) = delete;
+  void SetUpInProcessBrowserTestFixture() override {}
 
   content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
     return fenced_frame_helper_;
@@ -1552,6 +1564,7 @@
 
  private:
   content::test::FencedFrameTestHelper fenced_frame_helper_;
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(CommerceHintAgentFencedFrameTest,
@@ -1575,18 +1588,21 @@
 
 class CommerceHintAgentPortalBrowserTest : public CommerceHintAgentTest {
  public:
-  CommerceHintAgentPortalBrowserTest() {
-    scoped_feature_list_.InitWithFeatures(
-        /*enabled_features=*/{blink::features::kPortals,
-                              blink::features::kPortalsCrossOrigin},
-        /*disabled_features=*/{});
+  void SetUpInProcessBrowserTestFixture() override {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{blink::features::kPortals, {}},
+         {blink::features::kPortalsCrossOrigin, {}},
+         {
+#if !BUILDFLAG(IS_ANDROID)
+             ntp_features::kNtpChromeCartModule,
+#else
+             commerce::kCommerceHintAndroid,
+#endif
+             {{"product-skip-pattern", "(^|\\W)(?i)(skipped)(\\W|$)"},
+              // Extend timeout to avoid flakiness.
+              {"cart-extraction-timeout", "1m"}}}},
+        {optimization_guide::features::kOptimizationHints});
   }
-  ~CommerceHintAgentPortalBrowserTest() override = default;
-  CommerceHintAgentPortalBrowserTest(
-      const CommerceHintAgentPortalBrowserTest&) = delete;
-
-  CommerceHintAgentPortalBrowserTest& operator=(
-      const CommerceHintAgentPortalBrowserTest&) = delete;
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -1605,4 +1621,60 @@
 }
 #endif  // !BUILDFLAG(IS_CHROMEOS)
 
+#if !BUILDFLAG(IS_ANDROID)
+class CommerceHintFeatureDefaultWithoutGeoTest : public CommerceHintAgentTest {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {}, {optimization_guide::features::kOptimizationHints});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(CommerceHintFeatureDefaultWithoutGeoTest,
+                       DisableWithoutGeo) {
+  ASSERT_FALSE(IsCartModuleEnabled());
+
+  NavigateToURL("https://www.guitarcenter.com/cart.html");
+
+  WaitForUmaCount("Commerce.Carts.VisitCart", 0);
+  WaitForCartCount(kEmptyExpected);
+}
+
+class CommerceHintFeatureDefaultWithGeoTest : public CommerceHintAgentTest {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {}, {optimization_guide::features::kOptimizationHints});
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    CommerceHintAgentTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII(
+        variations::switches::kVariationsOverrideCountry, "us");
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(CommerceHintFeatureDefaultWithGeoTest, EnableWithGeo) {
+  auto locale = std::make_unique<ScopedBrowserLocale>("en-US");
+
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
+  ASSERT_TRUE(IsCartModuleEnabled());
+
+  NavigateToURL("https://www.guitarcenter.com/cart.html");
+  WaitForUmaCount("Commerce.Carts.VisitCart", 1);
+#else
+  ASSERT_FALSE(IsCartModuleEnabled());
+
+  WaitForUmaCount("Commerce.Carts.VisitCart", 0);
+  WaitForCartCount(kEmptyExpected);
+#endif
+}
+#endif
+
 }  // namespace
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 53ebf70..a7ac792 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -72,6 +72,7 @@
 #include "components/autofill/content/renderer/password_generation_agent.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill_assistant/content/renderer/autofill_assistant_agent.h"
+#include "components/commerce/core/commerce_feature_list.h"
 #include "components/content_capture/common/content_capture_features.h"
 #include "components/content_capture/renderer/content_capture_sender.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
@@ -169,7 +170,6 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "chrome/renderer/sandbox_status_extension_android.h"
-#include "components/commerce/core/commerce_feature_list.h"
 #else
 #include "chrome/renderer/searchbox/searchbox.h"
 #include "chrome/renderer/searchbox/searchbox_extension.h"
@@ -708,7 +708,7 @@
 // frame that is the main frame as well, so we should check if |render_frame|
 // is the fenced frame.
 #if !BUILDFLAG(IS_ANDROID)
-  if (base::FeatureList::IsEnabled(ntp_features::kNtpChromeCartModule) &&
+  if (command_line->HasSwitch(commerce::switches::kEnableChromeCart) &&
 #else
   if (base::FeatureList::IsEnabled(commerce::kCommerceHintAndroid) &&
 #endif  // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/services/util_win/DEPS b/chrome/services/util_win/DEPS
index df5b419..b50842f 100644
--- a/chrome/services/util_win/DEPS
+++ b/chrome/services/util_win/DEPS
@@ -2,6 +2,7 @@
   "+chrome/browser/win/conflicts/module_info.h",
   "+chrome/browser/win/conflicts/module_info_util.h",
   "+chrome/installer/util/registry_util.h",
+  "+chrome/installer/util/taskbar_util.h",
   "+content/public/utility/utility_thread.h",
   "+third_party/metrics_proto/system_profile.pb.h",
 ]
diff --git a/chrome/services/util_win/util_win_impl.cc b/chrome/services/util_win/util_win_impl.cc
index 3de58cd..2364375 100644
--- a/chrome/services/util_win/util_win_impl.cc
+++ b/chrome/services/util_win/util_win_impl.cc
@@ -24,6 +24,7 @@
 #include "base/win/win_util.h"
 #include "chrome/browser/win/conflicts/module_info_util.h"
 #include "chrome/installer/util/registry_util.h"
+#include "chrome/installer/util/taskbar_util.h"
 #include "chrome/services/util_win/av_products.h"
 #include "third_party/metrics_proto/system_profile.pb.h"
 #include "ui/shell_dialogs/execute_select_file_win.h"
@@ -247,7 +248,7 @@
     const std::vector<base::FilePath>& shortcut_paths,
     UnpinShortcutsCallback callback) {
   for (const auto& shortcut_path : shortcut_paths)
-    base::win::UnpinShortcutFromTaskbar(shortcut_path);
+    UnpinShortcutFromTaskbar(shortcut_path);
 
   std::move(callback).Run();
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 4b6e88ff..94a2be0 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -852,6 +852,7 @@
       "//components/ukm:ukm_test_helper",
       "//components/ukm/content",
       "//components/unified_consent",
+      "//components/variations/service",
       "//components/webapps/browser",
 
       # TODO(crbug.com/961849): This is needed for ShellManager which is what
@@ -4168,6 +4169,7 @@
         "//chrome/browser/ui/ash/system_web_apps",
         "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings",
         "//chrome/browser/ui/webui/chromeos/crostini_upgrader:mojo_bindings",
+        "//chrome/browser/ui/webui/chromeos/manage_mirrorsync:mojo_bindings",
         "//chrome/browser/ui/webui/chromeos/parent_access:mojo_bindings",
         "//chrome/browser/ui/webui/settings/chromeos/constants:mojom",
         "//chrome/services/file_util/public/cpp:browser_tests",
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc
index a7ecf7d..a3d6578 100644
--- a/chrome/test/chromedriver/capabilities.cc
+++ b/chrome/test/chromedriver/capabilities.cc
@@ -93,7 +93,8 @@
   const base::DictionaryValue* dict = NULL;
   if (!option.GetAsDictionary(&dict))
     return Status(kInvalidArgument, "must be a dictionary");
-  to_set->reset(dict->DeepCopy());
+  *to_set =
+      base::DictionaryValue::From(base::Value::ToUniquePtrValue(dict->Clone()));
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/chrome/devtools_client_impl.cc b/chrome/test/chromedriver/chrome/devtools_client_impl.cc
index 0d0843e6..243e7e26 100644
--- a/chrome/test/chromedriver/chrome/devtools_client_impl.cc
+++ b/chrome/test/chromedriver/chrome/devtools_client_impl.cc
@@ -591,8 +591,10 @@
     response_info->state = kReceived;
     response_info->response.id = response.id;
     response_info->response.error = response.error;
-    if (response.result)
-      response_info->response.result.reset(response.result->DeepCopy());
+    if (response.result) {
+      response_info->response.result = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(response.result->Clone()));
+    }
   }
 
   if (response.result) {
@@ -675,10 +677,12 @@
 
     *type = kEventMessageType;
     event->method = method;
-    if (params)
-      event->params.reset(params->DeepCopy());
-    else
+    if (params) {
+      event->params = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(params->Clone()));
+    } else {
       event->params = std::make_unique<base::DictionaryValue>();
+    }
     return true;
   } else if (id_value->is_int()) {
     base::DictionaryValue* unscoped_error = nullptr;
@@ -690,12 +694,14 @@
     // Tracing.start and Tracing.end command responses do not contain one.
     // So, if neither "error" nor "result" keys are present, just provide
     // a blank result dictionary.
-    if (message_dict->GetDictionary("result", &unscoped_result))
-      command_response->result.reset(unscoped_result->DeepCopy());
-    else if (message_dict->GetDictionary("error", &unscoped_error))
+    if (message_dict->GetDictionary("result", &unscoped_result)) {
+      command_response->result = base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(unscoped_result->Clone()));
+    } else if (message_dict->GetDictionary("error", &unscoped_error)) {
       base::JSONWriter::Write(*unscoped_error, &command_response->error);
-    else
+    } else {
       command_response->result = std::make_unique<base::DictionaryValue>();
+    }
     return true;
   }
   return false;
diff --git a/chrome/test/chromedriver/chrome/devtools_client_impl_unittest.cc b/chrome/test/chromedriver/chrome/devtools_client_impl_unittest.cc
index 5814198..ceeed466 100644
--- a/chrome/test/chromedriver/chrome/devtools_client_impl_unittest.cc
+++ b/chrome/test/chromedriver/chrome/devtools_client_impl_unittest.cc
@@ -70,7 +70,8 @@
         base::JSONReader::ReadDeprecated(message);
     base::DictionaryValue* temp_dict;
     EXPECT_TRUE(value->GetAsDictionary(&temp_dict));
-    dict->reset(temp_dict->DeepCopy());
+    *dict = base::DictionaryValue::From(
+        base::Value::ToUniquePtrValue(temp_dict->Clone()));
     if (!dict)
       return false;
     absl::optional<int> maybe_id = (*dict)->GetDict().FindInt("id");
diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc
index 8b028a8..090d02a 100644
--- a/chrome/test/chromedriver/commands.cc
+++ b/chrome/test/chromedriver/commands.cc
@@ -343,7 +343,8 @@
         base::BindOnce(
             &ExecuteSessionCommandOnSessionThread, command_name, command,
             w3c_standard_command, return_ok_without_session,
-            base::WrapUnique(params.DeepCopy()),
+            base::DictionaryValue::From(
+                base::Value::ToUniquePtrValue(params.Clone())),
             base::ThreadTaskRunnerHandle::Get(), callback,
             base::BindRepeating(&TerminateSessionThreadOnCommandThread,
                                 session_thread_map, session_id)));
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc
index 6f2e69e..5d4be7d 100644
--- a/chrome/test/chromedriver/element_commands.cc
+++ b/chrome/test/chromedriver/element_commands.cc
@@ -998,7 +998,7 @@
   ret.SetDoubleKey("y", maybe_y.value());
   ret.SetDoubleKey("width", maybe_width.value());
   ret.SetDoubleKey("height", maybe_height.value());
-  value->reset(ret.DeepCopy());
+  *value = base::Value::ToUniquePtrValue(ret.Clone());
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/performance_logger_unittest.cc b/chrome/test/chromedriver/performance_logger_unittest.cc
index 5a3fb87..e4af5299 100644
--- a/chrome/test/chromedriver/performance_logger_unittest.cc
+++ b/chrome/test/chromedriver/performance_logger_unittest.cc
@@ -71,8 +71,10 @@
   Status SendCommandAndGetResult(const std::string& method,
                                  const base::DictionaryValue& params,
                                  base::Value* result) override {
-    sent_commands_.push_back(
-        std::make_unique<DevToolsCommand>(method, params.DeepCopy()));
+    sent_commands_.push_back(std::make_unique<DevToolsCommand>(
+        method, base::DictionaryValue::From(
+                    base::Value::ToUniquePtrValue(params.Clone()))
+                    .release()));
     *result = base::Value(base::Value::Type::DICTIONARY);
     return Status(kOk);
   }
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc
index 5b72c7f9..d0784a2 100644
--- a/chrome/test/chromedriver/session_commands.cc
+++ b/chrome/test/chromedriver/session_commands.cc
@@ -337,10 +337,9 @@
     base::Value body(base::Value::Type::DICTIONARY);
     body.SetKey("capabilities", session->capabilities->Clone());
     body.SetStringKey("sessionId", session->id);
-    value->reset(base::Value::ToUniquePtrValue(body.Clone()).release());
+    *value = base::Value::ToUniquePtrValue(body.Clone());
   } else {
-    value->reset(base::Value::ToUniquePtrValue(session->capabilities->Clone())
-                     .release());
+    *value = base::Value::ToUniquePtrValue(session->capabilities->Clone());
   }
   return CheckSessionCreated(session);
 }
@@ -652,7 +651,7 @@
 Status ExecuteGetSessionCapabilities(Session* session,
                                      const base::DictionaryValue& params,
                                      std::unique_ptr<base::Value>* value) {
-  value->reset(session->capabilities->DeepCopy());
+  *value = base::Value::ToUniquePtrValue(session->capabilities->Clone());
   return Status(kOk);
 }
 
@@ -949,7 +948,7 @@
                         session->page_load_timeout.InMilliseconds());
   SetSafeInt(&timeouts, "implicit", session->implicit_wait.InMilliseconds());
 
-  value->reset(base::Value::ToUniquePtrValue(timeouts.Clone()).release());
+  *value = base::Value::ToUniquePtrValue(timeouts.Clone());
   return Status(kOk);
 }
 
@@ -1010,7 +1009,7 @@
   // Set a dummy altitude to make WebDriver clients happy.
   // https://code.google.com/p/chromedriver/issues/detail?id=281
   location.SetDoubleKey("altitude", 0);
-  value->reset(base::Value::ToUniquePtrValue(location.Clone()).release());
+  *value = base::Value::ToUniquePtrValue(location.Clone());
   return Status(kOk);
 }
 
@@ -1049,7 +1048,7 @@
   conditions.SetIntKey(
       "upload_throughput",
       session->overridden_network_conditions->upload_throughput);
-  value->reset(base::Value::ToUniquePtrValue(conditions.Clone()).release());
+  *value = base::Value::ToUniquePtrValue(conditions.Clone());
   return Status(kOk);
 }
 
@@ -1136,7 +1135,7 @@
   base::Value position(base::Value::Type::DICTIONARY);
   position.SetIntKey("x", windowRect.x);
   position.SetIntKey("y", windowRect.y);
-  value->reset(base::Value::ToUniquePtrValue(position.Clone()).release());
+  *value = base::Value::ToUniquePtrValue(position.Clone());
   return Status(kOk);
 }
 
@@ -1168,7 +1167,7 @@
   base::Value size(base::Value::Type::DICTIONARY);
   size.SetIntKey("width", windowRect.width);
   size.SetIntKey("height", windowRect.height);
-  value->reset(base::Value::ToUniquePtrValue(size.Clone()).release());
+  *value = base::Value::ToUniquePtrValue(size.Clone());
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 9641dfec..938e916 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -2339,7 +2339,8 @@
   for (std::list<Cookie>::const_iterator it = cookies.begin();
        it != cookies.end(); ++it) {
     if (name == it->name) {
-      value->reset(CreateDictionaryFrom(*it)->DeepCopy());
+      *value =
+          base::Value::ToUniquePtrValue(CreateDictionaryFrom(*it)->Clone());
       return Status(kOk);
     }
   }
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/help_content_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/help_content_test.js
index 2909a55..6513091 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/help_content_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/help_content_test.js
@@ -118,9 +118,11 @@
     assertTrue(!!title);
     assertEquals('Top help content', title.textContent);
 
-    // Vierfy the description Icon is in the page.
-    const descriptionIcon = getElement('#helpContentIcon');
-    assertTrue(!!descriptionIcon);
+    // Verify the help content Icon is in the page.
+    const helpContentIcon = getElement('#helpContentIcon');
+    assertTrue(!!helpContentIcon);
+    // The help content icon is not visible.
+    assertFalse(isVisible(helpContentIcon));
 
     verifyPopularHelpContent();
   });
@@ -139,6 +141,9 @@
     assertTrue(!!title);
     assertEquals('Suggested help content', title.textContent);
 
+    // The help content icon is visible.
+    assertTrue(isVisible(getElement('#helpContentIcon')));
+
     // Verify the help content is populated with correct number of items.
     assertEquals(5, getElement('dom-repeat').items.length);
     const helpLinks =
@@ -196,6 +201,9 @@
     assertEquals(
         'No suggested content. See top help content.', title.textContent);
 
+    // The help content icon is not visible.
+    assertFalse(isVisible(getElement('#helpContentIcon')));
+
     verifyPopularHelpContent();
   });
 
diff --git a/chrome/test/data/webui/settings/search_engines_page_test.ts b/chrome/test/data/webui/settings/search_engines_page_test.ts
index 2553ff08..7f15f0d8 100644
--- a/chrome/test/data/webui/settings/search_engines_page_test.ts
+++ b/chrome/test/data/webui/settings/search_engines_page_test.ts
@@ -165,24 +165,9 @@
   });
 
   // Test that the <search-engine-entry> is populated according to its
-  // underlying SearchEngine model.
-  test('Initialization', function() {
-    assertEquals(
-        searchEngine.displayName,
-        entry.shadowRoot!.querySelector('#name-column')!.textContent!.trim());
-    assertEquals(
-        searchEngine.keyword,
-        entry.shadowRoot!.querySelector('#keyword-column')!.textContent);
-    assertEquals(
-        searchEngine.url,
-        entry.shadowRoot!.querySelector('#url-column')!.textContent);
-  });
-
-  // Test that the <search-engine-entry> is populated according to its
   // underlying SearchEngine model. If the #omnibox-active-search-engines flag
   // is enabled, show the shortcut column instead of the keyword column.
-  test('Initialization_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Initialization', function() {
     flush();
     assertEquals(
         searchEngine.displayName,
@@ -192,12 +177,11 @@
         entry.shadowRoot!.querySelector('#shortcut-column')!.textContent);
     assertEquals(
         searchEngine.url,
-        entry.shadowRoot!.querySelector('#url-column')!.textContent);
+        entry.shadowRoot!.querySelector('#url-column-padded')!.textContent);
   });
 
   // Tests that columns are hidden and shown appropriately.
-  test('ColumnVisibility_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('ColumnVisibility', function() {
     flush();
 
     // Test shortcut column visibility.
@@ -220,11 +204,19 @@
                              '#url-column-padded')!.hidden);
   });
 
-  test('Remove_Enabled', async function() {
-    // Open action menu.
-    entry.shadowRoot!.querySelector('cr-icon-button')!.click();
+  // Open and return the action menu
+  function openActionMenu() {
+    const menuButton = entry.shadowRoot!.querySelector<HTMLElement>(
+        'cr-icon-button.icon-more-vert');
+    assertTrue(!!menuButton);
+    menuButton!.click();
     const menu = entry.shadowRoot!.querySelector('cr-action-menu')!;
     assertTrue(menu.open);
+    return menu;
+  }
+
+  test('Remove_Enabled', async function() {
+    const menu = openActionMenu();
 
     const deleteButton = entry.$.delete;
     assertTrue(!!deleteButton);
@@ -236,10 +228,7 @@
   });
 
   test('MakeDefault_Enabled', async function() {
-    // Open action menu.
-    entry.shadowRoot!.querySelector('cr-icon-button')!.click();
-    const menu = entry.shadowRoot!.querySelector('cr-action-menu')!;
-    assertTrue(menu.open);
+    const menu = openActionMenu();
 
     const makeDefaultButton = entry.$.makeDefault;
     assertTrue(!!makeDefaultButton);
@@ -251,32 +240,6 @@
 
   // Test that clicking the "edit" menu item fires an edit event.
   test('Edit_Enabled', function() {
-    // Open action menu.
-    entry.shadowRoot!
-        .querySelector<HTMLElement>('cr-icon-button.icon-more-vert')!.click();
-    const menu = entry.shadowRoot!.querySelector('cr-action-menu')!;
-    assertTrue(menu.open);
-
-    const engine = entry.engine;
-    const editButton = entry.$.edit;
-    assertTrue(!!editButton);
-    assertFalse(editButton.hidden);
-
-    const promise = eventToPromise('edit-search-engine', entry).then(e => {
-      assertEquals(engine, e.detail.engine);
-      assertEquals(
-          entry.shadowRoot!.querySelector('cr-icon-button'),
-          e.detail.anchorElement);
-    });
-    editButton.click();
-    return promise;
-  });
-
-  // Test that clicking the "edit" menu item fires an edit event. If the
-  // #omnibox-active-search-engines flag is enabled, the edit button is an icon
-  // button inline with the Search Engine entry and not in the 3-dot menu.
-  test('Edit_Enabled_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
     flush();
 
     const engine = entry.engine;
@@ -310,22 +273,19 @@
     testButtonHidden(createSampleSearchEngine({canBeRemoved: false}), 'delete');
   });
 
-  test('Activate_Hidden_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Activate_Hidden', function() {
     flush();
     testButtonHidden(
         createSampleSearchEngine({canBeActivated: false}), 'activate');
   });
 
-  test('Deactivate_Hidden_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Deactivate_Hidden', function() {
     flush();
     testButtonHidden(
         createSampleSearchEngine({canBeDeactivated: false}), 'deactivate');
   });
 
-  test('Edit_Hidden_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Edit_Hidden', function() {
     flush();
     testButtonHidden(
         createSampleSearchEngine({canBeActivated: true}), 'editIconButton');
@@ -347,19 +307,13 @@
   });
 
   test('Edit_Disabled', function() {
-    testButtonDisabled(createSampleSearchEngine({canBeEdited: false}), 'edit');
-  });
-
-  test('Edit_Disabled_ActiveFlagEnabled', function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
     flush();
     testButtonDisabled(
         createSampleSearchEngine({canBeEdited: false}), 'editIconButton');
   });
 
   // Test that clicking the "activate" button fires an activate event.
-  test('Activate_ActiveFlagEnabled', async function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Activate', async function() {
     flush();
     entry.engine = createSampleSearchEngine({canBeActivated: true});
 
@@ -377,8 +331,7 @@
   });
 
   // Test that clicking the "Deactivate" button fires a deactivate event.
-  test('Deactivate_ActiveFlagEnabled', async function() {
-    entry.set('isActiveSearchEnginesFlagEnabled', true);
+  test('Deactivate', async function() {
     flush();
     entry.engine = createSampleSearchEngine({canBeDeactivated: true});
 
@@ -404,29 +357,62 @@
 
 suite('SearchEnginePageTests', function() {
   let page: SettingsSearchEnginesPageElement;
+  let searchEnginesLists: NodeListOf<SettingsSearchEnginesListElement>;
   let browserProxy: TestSearchEnginesBrowserProxy;
 
   const searchEnginesInfo: SearchEnginesInfo = {
-    defaults: [createSampleSearchEngine({
-      id: 0,
-      name: 'search_engine_G',
-      displayName: 'search_engine_G displayName',
-      keyword: 'search_engine_G',
-    })],
-    actives: [],
-    others: [
+    defaults: [
+      createSampleSearchEngine({
+        id: 0,
+        name: 'search_engine_default_A',
+        displayName: 'A displayName',
+        keyword: 'default A',
+      }),
       createSampleSearchEngine({
         id: 1,
-        name: 'search_engine_B',
-        displayName: 'search_engine_B displayName',
-        keyword: 'search_engine_B',
+        name: 'search_engine_default_B',
+        displayName: 'B displayName',
+        keyword: 'default B',
       }),
       createSampleSearchEngine({
         id: 2,
-        name: 'search_engine_A',
-        displayName: 'search_engine_A displayName',
-        keyword: 'search_engine_A',
+        name: 'search_engine_default_C',
+        displayName: 'C displayName',
+        keyword: 'default C',
       }),
+      createSampleSearchEngine({
+        id: 3,
+        name: 'search_engine_default_D',
+        displayName: 'D displayName',
+        keyword: 'default D',
+      }),
+      createSampleSearchEngine({
+        id: 4,
+        name: 'search_engine_default_E',
+        displayName: 'E displayName',
+        keyword: 'default E',
+      }),
+      createSampleSearchEngine({
+        id: 5,
+        name: 'search_engine_default_F',
+        displayName: 'F displayName',
+        keyword: 'default F',
+      }),
+    ],
+    actives: [createSampleSearchEngine({id: 6})],
+    others: [
+      createSampleSearchEngine({
+        id: 7,
+        name: 'search_engine_G',
+        displayName: 'search_engine_G displayName',
+      }),
+      createSampleSearchEngine(
+          {id: 8, name: 'search_engine_F', keyword: 'search_engine_F keyword'}),
+      createSampleSearchEngine({id: 9, name: 'search_engine_E'}),
+      createSampleSearchEngine({id: 10, name: 'search_engine_D'}),
+      createSampleSearchEngine({id: 11, name: 'search_engine_C'}),
+      createSampleSearchEngine({id: 12, name: 'search_engine_B'}),
+      createSampleSearchEngine({id: 13, name: 'search_engine_A'}),
     ],
     extensions: [createSampleOmniboxExtension()],
   };
@@ -462,34 +448,107 @@
   // Tests that the page is querying and displaying search engine info on
   // startup.
   test('Initialization', function() {
-    const searchEnginesLists =
+    searchEnginesLists =
         page.shadowRoot!.querySelectorAll('settings-search-engines-list');
-    assertEquals(2, searchEnginesLists.length);
+    assertEquals(3, searchEnginesLists.length);
 
     flush();
-    const defaultsList = searchEnginesLists[0]!;
-    const defaultsEntries = defaultsList.shadowRoot!.querySelectorAll(
-        'settings-search-engine-entry');
-    assertEquals(searchEnginesInfo.defaults.length, defaultsEntries.length);
+  });
 
-    const othersList = searchEnginesLists[1]!;
-    const othersEntries =
-        othersList.shadowRoot!.querySelectorAll('settings-search-engine-entry');
-    assertEquals(searchEnginesInfo.others.length, othersEntries.length);
+  test('testDefaultsList', function() {
+    const defaultsListElement = searchEnginesLists[0]!;
+
+    // The defaults list should only show the name and shortcut columns.
+    assertFalse(
+        defaultsListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
+            'hidden'));
+    assertFalse(defaultsListElement.shadowRoot!.querySelector('.shortcut')!
+                    .hasAttribute('hidden'));
+    assertTrue(defaultsListElement.shadowRoot!.querySelector('.url-padded')!
+                   .hasAttribute('hidden'));
+
+    // The default engines list should not collapse and should show all entries
+    // in the list by default.
+    const lists =
+        defaultsListElement.shadowRoot!.querySelectorAll('dom-repeat')!;
+    assertEquals(1, lists.length);
+    const defaultsEntries = lists[0]!.items;
+    assertEquals(searchEnginesInfo.defaults.length, defaultsEntries!.length);
+  });
+
+  test('testActivesList', function() {
+    const activesListElement = searchEnginesLists[1]!;
+
+    // The actives list should only show the name and shortcut columns.
+    assertFalse(
+        activesListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
+            'hidden'));
+    assertFalse(
+        activesListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute(
+            'hidden'));
+    assertTrue(activesListElement.shadowRoot!.querySelector('.url-padded')!
+                   .hasAttribute('hidden'));
+
+    // With less than `visibleEnginesSize` elements in the list, all elements
+    // should be visible and the collapsible section should not be present.
+    const lists = activesListElement.shadowRoot!.querySelectorAll('dom-repeat');
+    const visibleEntries = lists[0]!.items;
+    const collapsedEntries = lists[1]!.items;
+    assertEquals(searchEnginesInfo.actives.length, visibleEntries!.length);
+    assertEquals(0, collapsedEntries!.length);
+
+    const expandButton =
+        activesListElement.shadowRoot!.querySelector('cr-expand-button');
+    assertTrue(!!expandButton);
+    assertTrue(expandButton!.hasAttribute('hidden'));
+  });
+
+  test('testOthersList', function() {
+    const othersListElement = searchEnginesLists[2]!;
+
+    // The others list should only show the name and url columns.
+    assertFalse(
+        othersListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
+            'hidden'));
+    assertTrue(
+        othersListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute(
+            'hidden'));
+    assertFalse(othersListElement.shadowRoot!.querySelector('.url-padded')!
+                    .hasAttribute('hidden'));
+
+    // Any engines greater than `visibleEnginesSize` will be in a second list
+    // under the collapsible section. The button to expand this section must be
+    // visible.
+    const visibleEnginesSize = othersListElement.visibleEnginesSize;
+    const lists = othersListElement.shadowRoot!.querySelectorAll('dom-repeat');
+    const visibleEntries = lists[0]!.items;
+    const collapsedEntries = lists[1]!.items;
+    assertEquals(visibleEnginesSize, visibleEntries!.length);
+    assertEquals(
+        searchEnginesInfo.others.length - visibleEnginesSize,
+        collapsedEntries!.length);
 
     // Ensure that the search engines have reverse alphabetical order in the
     // model.
-    assertTrue(
-        searchEnginesInfo.others[0]!.name > searchEnginesInfo.others[1]!.name);
+    for (let i = 0; i < searchEnginesInfo.others.length - 1; i++) {
+      assertTrue(
+          searchEnginesInfo.others[i]!.name >=
+          searchEnginesInfo.others[i + 1]!.name);
+    }
+
+    const othersEntries = othersListElement!.shadowRoot!.querySelectorAll(
+        'settings-search-engine-entry');
 
     // Ensure that they are displayed in alphabetical order.
-    assertEquals(
-        searchEnginesInfo.others[1]!.name, othersEntries[0]!.engine.name);
-    assertEquals(
-        searchEnginesInfo.others[0]!.name, othersEntries[1]!.engine.name);
+    for (let i = 0; i < othersEntries!.length - 1; i++) {
+      assertTrue(
+          othersEntries[i]!.engine.name <= othersEntries[i + 1]!.engine.name);
+    }
 
-    const extensionEntries = page.shadowRoot!.querySelector('iron-list')!.items;
-    assertEquals(searchEnginesInfo.extensions.length, extensionEntries!.length);
+    const expandButton =
+        othersListElement.shadowRoot!.querySelector('cr-expand-button');
+    assertTrue(!!expandButton);
+    assertFalse(expandButton!.hasAttribute('hidden'));
   });
 
   // Test that the keyboard shortcut radio buttons are shown as expected, and
@@ -592,8 +651,12 @@
   test('FilterSearchEngines', function() {
     flush();
 
+    // TODO: Lookup via array index  may not be the best approach, because
+    // changing the order or number of settings-search-engines-list elements
+    // can break this test. Maybe we can add an id to every relevant element and
+    // use that for lookup.
     function getListItems(listIndex: number) {
-      const list = listIndex === 2 /* extensions */ ?
+      const list = listIndex === 3 /* extensions */ ?
           page.shadowRoot!.querySelector('iron-list')!.items :
           page.shadowRoot!
               .querySelectorAll('settings-search-engines-list')[listIndex]!
@@ -605,17 +668,17 @@
     function assertSearchResults(
         defaultsCount: number, othersCount: number, extensionsCount: number) {
       assertEquals(defaultsCount, getListItems(0)!.length);
-      assertEquals(othersCount, getListItems(1)!.length);
-      assertEquals(extensionsCount, getListItems(2)!.length);
+      assertEquals(othersCount, getListItems(2)!.length);
+      assertEquals(extensionsCount, getListItems(3)!.length);
 
       const noResultsElements = Array.from(
           page.shadowRoot!.querySelectorAll<HTMLElement>('.no-search-results'));
       assertEquals(defaultsCount > 0, noResultsElements[0]!.hidden);
-      assertEquals(othersCount > 0, noResultsElements[1]!.hidden);
-      assertEquals(extensionsCount > 0, noResultsElements[2]!.hidden);
+      assertEquals(othersCount > 0, noResultsElements[2]!.hidden);
+      assertEquals(extensionsCount > 0, noResultsElements[3]!.hidden);
     }
 
-    assertSearchResults(1, 2, 1);
+    assertSearchResults(6, 7, 1);
 
     // Search by name
     page.filter = searchEnginesInfo.defaults[0]!.name;
@@ -635,7 +698,7 @@
     // Search by URL
     page.filter = 'search?';
     flush();
-    assertSearchResults(1, 2, 0);
+    assertSearchResults(6, 7, 0);
 
     // Test case where none of the sublists have results.
     page.filter = 'does not exist';
@@ -647,146 +710,6 @@
     flush();
     assertSearchResults(0, 0, 1);
   });
-});
-
-suite('SearchEnginePageTests_ActiveFlagEnabled', function() {
-  let page: SettingsSearchEnginesPageElement;
-  let searchEnginesLists: NodeListOf<SettingsSearchEnginesListElement>;
-  let browserProxy: TestSearchEnginesBrowserProxy;
-
-  const searchEnginesInfo: SearchEnginesInfo = {
-    defaults: [
-      createSampleSearchEngine({id: 0}),
-      createSampleSearchEngine({id: 1}),
-      createSampleSearchEngine({id: 2}),
-      createSampleSearchEngine({id: 3}),
-      createSampleSearchEngine({id: 4}),
-      createSampleSearchEngine({id: 5}),
-    ],
-    actives: [createSampleSearchEngine({id: 6})],
-    others: [
-      createSampleSearchEngine({id: 7}),
-      createSampleSearchEngine({id: 8}),
-      createSampleSearchEngine({id: 9}),
-      createSampleSearchEngine({id: 10}),
-      createSampleSearchEngine({id: 11}),
-      createSampleSearchEngine({id: 12}),
-      createSampleSearchEngine({id: 13}),
-    ],
-    extensions: [createSampleOmniboxExtension()],
-  };
-
-  setup(function() {
-    browserProxy = new TestSearchEnginesBrowserProxy();
-
-    // Purposefully pass a clone of |searchEnginesInfo| to avoid any
-    // mutations on ground truth data.
-    browserProxy.setSearchEnginesInfo({
-      defaults: searchEnginesInfo.defaults.slice(),
-      actives: searchEnginesInfo.actives.slice(),
-      others: searchEnginesInfo.others.slice(),
-      extensions: searchEnginesInfo.extensions.slice(),
-    });
-    loadTimeData.overrideValues({'isActiveSearchEnginesFlagEnabled': true});
-    SearchEnginesBrowserProxyImpl.setInstance(browserProxy);
-    document.body.innerHTML = '';
-    page = document.createElement('settings-search-engines-page');
-    document.body.appendChild(page);
-    return browserProxy.whenCalled('getSearchEnginesList');
-  });
-
-  teardown(function() {
-    page.remove();
-  });
-
-  // Tests that the page is querying and displaying search engine info on
-  // startup.
-  test('Initialization', function() {
-    searchEnginesLists =
-        page.shadowRoot!.querySelectorAll('settings-search-engines-list');
-    assertEquals(3, searchEnginesLists.length);
-  });
-
-  test('testDefaultsList', function() {
-    const defaultsListElement = searchEnginesLists[0]!;
-
-    // The defaults list should only show the name and shortcut columns.
-    assertFalse(
-        defaultsListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
-            'hidden'));
-    assertFalse(defaultsListElement.shadowRoot!.querySelector('.shortcut')!
-                    .hasAttribute('hidden'));
-    assertTrue(
-        defaultsListElement.shadowRoot!.querySelector('.url')!.hasAttribute(
-            'hidden'));
-
-    // The default engines list should not collapse and should show all entries
-    // in the list by default.
-    const lists =
-        defaultsListElement.shadowRoot!.querySelectorAll('dom-repeat')!;
-    assertEquals(1, lists.length);
-    const defaultsEntries = lists[0]!.items;
-    assertEquals(searchEnginesInfo.defaults.length, defaultsEntries!.length);
-  });
-
-  test('testActivesList', function() {
-    const activesListElement = searchEnginesLists[1]!;
-
-    // The actives list should only show the name and shortcut columns.
-    assertFalse(
-        activesListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
-            'hidden'));
-    assertFalse(
-        activesListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute(
-            'hidden'));
-    assertTrue(
-        activesListElement.shadowRoot!.querySelector('.url')!.hasAttribute(
-            'hidden'));
-
-    // With less than `visibleEnginesSize` elements in the list, all elements
-    // should be visible and the collapsible section should not be present.
-    const lists = activesListElement.shadowRoot!.querySelectorAll('dom-repeat');
-    const visibleEntries = lists[0]!.items;
-    const collapsedEntries = lists[1]!.items;
-    assertEquals(searchEnginesInfo.actives.length, visibleEntries!.length);
-    assertEquals(0, collapsedEntries!.length);
-
-    const expandButton =
-        activesListElement.shadowRoot!.querySelector('cr-expand-button');
-    assertTrue(!!expandButton);
-    assertTrue(expandButton!.hasAttribute('hidden'));
-  });
-
-  test('testOthersList', function() {
-    const othersListElement = searchEnginesLists[2]!;
-
-    // The others list should only show the name and url columns.
-    assertFalse(
-        othersListElement.shadowRoot!.querySelector('.name')!.hasAttribute(
-            'hidden'));
-    assertTrue(
-        othersListElement.shadowRoot!.querySelector('.shortcut')!.hasAttribute(
-            'hidden'));
-    assertFalse(othersListElement.shadowRoot!.querySelector('.url-padded')!
-                    .hasAttribute('hidden'));
-
-    // Any engines greater than `visibleEnginesSize` will be in a second list
-    // under the collapsible section. The button to expand this section must be
-    // visible.
-    const visibleEnginesSize = othersListElement.visibleEnginesSize;
-    const lists = othersListElement.shadowRoot!.querySelectorAll('dom-repeat');
-    const visibleEntries = lists[0]!.items;
-    const collapsedEntries = lists[1]!.items;
-    assertEquals(visibleEnginesSize, visibleEntries!.length);
-    assertEquals(
-        searchEnginesInfo.others.length - visibleEnginesSize,
-        collapsedEntries!.length);
-
-    const expandButton =
-        othersListElement.shadowRoot!.querySelector('cr-expand-button');
-    assertTrue(!!expandButton);
-    assertFalse(expandButton!.hasAttribute('hidden'));
-  });
 
   // Test that the "no other search engines" message is shown/hidden as
   // expected.
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index f289abb..14ff49fe 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -370,7 +370,10 @@
   source_set("constants_header") {
     sources = [ "constants.h" ]
 
-    deps = [ "//components/update_client" ]
+    deps = [
+      "//base",
+      "//components/update_client",
+    ]
   }
 
   source_set("constants_prod") {
@@ -829,6 +832,7 @@
       ]
     }
     if (is_win) {
+      deps += [ "//chrome/installer/util:with_no_strings" ]
       data_deps = [
         ":test_service_files",
         "//third_party/updater:old_updater",
@@ -861,6 +865,7 @@
       ]
     }
     if (is_win) {
+      deps += [ "//chrome/installer/util:with_no_strings" ]
       data_deps += [
         ":test_service_files",
         "//third_party/updater:old_updater",
diff --git a/chrome/updater/app/app_server.h b/chrome/updater/app/app_server.h
index b439be6..3ff6fad 100644
--- a/chrome/updater/app/app_server.h
+++ b/chrome/updater/app/app_server.h
@@ -35,6 +35,8 @@
     return external_constants_;
   }
 
+  scoped_refptr<const UpdaterPrefs> prefs() const { return prefs_; }
+
   // Overrides of App.
   void Uninitialize() override;
 
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc
index 4928067..10b0614d 100644
--- a/chrome/updater/app/server/win/com_classes_legacy.cc
+++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -9,6 +9,7 @@
 #include <windows.h>
 #include <wrl/client.h>
 
+#include <functional>
 #include <string>
 #include <vector>
 
@@ -25,6 +26,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
@@ -37,8 +39,10 @@
 #include "chrome/updater/app/server/win/server.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/external_constants.h"
+#include "chrome/updater/persisted_data.h"
 #include "chrome/updater/policy/manager.h"
 #include "chrome/updater/policy/service.h"
+#include "chrome/updater/prefs.h"
 #include "chrome/updater/update_service.h"
 #include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
@@ -844,11 +848,61 @@
   return S_OK;
 }
 
-// TODO(crbug.com/1293203): Implement this method.
 STDMETHODIMP PolicyStatusImpl::get_lastCheckedTime(DATE* last_checked) {
   DCHECK(last_checked);
 
-  return E_NOTIMPL;
+  using PolicyStatusImplPtr = Microsoft::WRL::ComPtr<PolicyStatusImpl>;
+
+  // TODO(crbug.com/1349988): perhaps implement a shared scoped memory that
+  // outlives the lambda instead of these local variables.
+  base::WaitableEvent get_last_checked_complete_event;
+  bool succeeded = false;
+  DATE last_checked_variant_time = {};
+
+  AppServerSingletonInstance()->main_task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](PolicyStatusImplPtr obj, base::WaitableEvent& event,
+             bool& succeeded, DATE& last_checked_variant_time) {
+            const base::ScopedClosureRunner signal_event(base::BindOnce(
+                [](base::WaitableEvent& event) { event.Signal(); },
+                std::ref(event)));
+
+            const auto persisted_data =
+                base::MakeRefCounted<const PersistedData>(
+                    AppServerSingletonInstance()->prefs()->GetPrefService());
+            if (!persisted_data)
+              return;
+
+            const base::Time last_checked_time =
+                persisted_data->GetLastChecked();
+            if (last_checked_time.is_null())
+              return;
+
+            const FILETIME last_checked_filetime =
+                last_checked_time.ToFileTime();
+            FILETIME file_time_local = {};
+            SYSTEMTIME system_time = {};
+            succeeded =
+                ::FileTimeToLocalFileTime(&last_checked_filetime,
+                                          &file_time_local) &&
+                ::FileTimeToSystemTime(&file_time_local, &system_time) &&
+                ::SystemTimeToVariantTime(&system_time,
+                                          &last_checked_variant_time);
+          },
+          PolicyStatusImplPtr(this), std::ref(get_last_checked_complete_event),
+          std::ref(succeeded), std::ref(last_checked_variant_time)));
+
+  if (!get_last_checked_complete_event.TimedWait(base::Seconds(60))) {
+    NOTREACHED();
+    return E_FAIL;
+  }
+
+  if (!succeeded)
+    return E_FAIL;
+
+  *last_checked = last_checked_variant_time;
+  return S_OK;
 }
 
 // TODO(crbug.com/1293203): Implement this method.
diff --git a/chrome/updater/app/server/win/server.h b/chrome/updater/app/server/win/server.h
index 292bc5ee..0c7ab67d 100644
--- a/chrome/updater/app/server/win/server.h
+++ b/chrome/updater/app/server/win/server.h
@@ -54,6 +54,8 @@
     return update_service_internal_;
   }
 
+  scoped_refptr<const UpdaterPrefs> prefs() const { return AppServer::prefs(); }
+
   // Handles COM factory unregistration then triggers program shutdown. This
   // function runs on a COM RPC thread when the WRL module is destroyed.
   void Stop();
diff --git a/chrome/updater/constants.h b/chrome/updater/constants.h
index 499c37be..ec530c71 100644
--- a/chrome/updater/constants.h
+++ b/chrome/updater/constants.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_UPDATER_CONSTANTS_H_
 #define CHROME_UPDATER_CONSTANTS_H_
 
+#include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/update_client/update_client_errors.h"
 
@@ -200,11 +201,11 @@
 extern const char kDevOverrideFileName[];
 
 // Timing constants.
-#if BUILDFLAG(IS_WIN)
-// How long to wait for an application installer (such as
-// chrome_installer.exe) to complete.
-constexpr int kWaitForAppInstallerSec = 60;
+// How long to wait for an application installer (such as chrome_installer.exe)
+// to complete.
+constexpr base::TimeDelta kWaitForAppInstaller = base::Minutes(15);
 
+#if BUILDFLAG(IS_WIN)
 // How often the installer progress from registry is sampled. This value may
 // be changed to provide a smoother progress experience (crbug.com/1067475).
 constexpr int kWaitForInstallerProgressSec = 1;
diff --git a/chrome/updater/installer.cc b/chrome/updater/installer.cc
index d0a4415..f72fe5e 100644
--- a/chrome/updater/installer.cc
+++ b/chrome/updater/installer.cc
@@ -16,6 +16,7 @@
 #include "base/notreached.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/scoped_blocking_call.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/updater/action_handler.h"
@@ -179,7 +180,7 @@
       application_installer, install_params->arguments,
       WriteInstallerDataToTempFile(unpack_path,
                                    install_params->server_install_data),
-      std::move(progress_callback));
+      kWaitForAppInstaller, std::move(progress_callback));
 }
 
 void Installer::InstallWithSyncPrimitives(
@@ -249,6 +250,7 @@
     const base::FilePath& /*app_installer*/,
     const std::string& /*arguments*/,
     const absl::optional<base::FilePath>& /*install_data_file*/,
+    const base::TimeDelta& timeout,
     InstallProgressCallback /*progress_callback*/) {
   NOTIMPLEMENTED();
   return AppInstallerResult(-1);
diff --git a/chrome/updater/installer.h b/chrome/updater/installer.h
index 1d52987..0c096b8 100644
--- a/chrome/updater/installer.h
+++ b/chrome/updater/installer.h
@@ -21,6 +21,10 @@
 #include "components/update_client/update_client.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+namespace base {
+class TimeDelta;
+}
+
 namespace updater {
 
 struct AppInfo {
@@ -52,6 +56,7 @@
     const base::FilePath& installer_path,
     const std::string& install_args,
     const absl::optional<base::FilePath>& server_install_data,
+    const base::TimeDelta& timeout,
     InstallProgressCallback progress_callback);
 
 // Manages the install of one application. Some of the functions of this
diff --git a/chrome/updater/installer_mac.cc b/chrome/updater/installer_mac.cc
index 6faa624..219308ff5 100644
--- a/chrome/updater/installer_mac.cc
+++ b/chrome/updater/installer_mac.cc
@@ -8,6 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/strings/strcat.h"
+#include "base/time/time.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/mac/install_from_archive.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -19,13 +20,14 @@
     const base::FilePath& app_installer,
     const std::string& arguments,
     const absl::optional<base::FilePath>& installer_data_file,
+    const base::TimeDelta& timeout,
     InstallProgressCallback /*progress_callback*/) {
   VLOG(1) << "Running application install from DMG at " << app_installer;
   // InstallFromArchive() returns the exit code of the script. 0 is success and
   // anything else should be an error.
   const int exit_code = InstallFromArchive(
       app_installer, app_info.ecp, app_info.ap, app_info.scope,
-      app_info.version, arguments, installer_data_file);
+      app_info.version, arguments, installer_data_file, timeout);
   return exit_code == 0
              ? AppInstallerResult()
              : AppInstallerResult(kErrorApplicationInstallerFailed, exit_code);
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn
index ee652c1..ff050f6 100644
--- a/chrome/updater/mac/BUILD.gn
+++ b/chrome/updater/mac/BUILD.gn
@@ -8,6 +8,7 @@
 import("//build/config/python.gni")
 import("//build/util/process_version.gni")
 import("//chrome/updater/branding.gni")
+import("//chrome/updater/zip.gni")
 import("//chrome/version.gni")
 
 group("mac") {
@@ -17,6 +18,7 @@
     ":updater_bundle",
     ":updater_bundle_test",
     ":updater_install_script",
+    ":updater_zip",
     "//chrome/updater/mac/installer:metainstaller",
     "//chrome/updater/mac/signing",
   ]
@@ -383,3 +385,51 @@
                        root_out_dir)
   }
 }
+
+# The contents of this zip are uploaded by archivers (//infra/archive_config).
+artifact_zip("updater_zip") {
+  output = "$root_build_dir/updater.zip"
+  inputs = [
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/MacOS/${updater_product_full_name}",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/MacOS/$keystone_app_name",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksinstall",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/MacOS/${keystone_app_name}Agent",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}.app/Contents/PkgInfo",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/MacOS/${updater_product_full_name}_test",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/MacOS/$keystone_app_name",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksinstall",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Helpers/ksadmin",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/MacOS/${keystone_app_name}Agent",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Resources/${keystone_app_name}Agent.app/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/Helpers/$keystone_app_name.bundle/Contents/Info.plist",
+    "$root_build_dir/${updater_product_full_name}_test.app/Contents/PkgInfo",
+    "$root_build_dir/Updater Packaging/signing/signing.py",
+    "$root_build_dir/Updater Packaging/signing/config.py",
+    "$root_build_dir/Updater Packaging/signing/modification.py",
+    "$root_build_dir/Updater Packaging/signing/notarize.py",
+    "$root_build_dir/Updater Packaging/signing/pkg-dmg",
+    "$root_build_dir/Updater Packaging/signing/__init__.py",
+    "$root_build_dir/Updater Packaging/signing/model.py",
+    "$root_build_dir/Updater Packaging/signing/unbranded_config.py",
+    "$root_build_dir/Updater Packaging/signing/pipeline.py",
+    "$root_build_dir/Updater Packaging/signing/parts.py",
+    "$root_build_dir/Updater Packaging/signing/config_factory.py",
+    "$root_build_dir/Updater Packaging/signing/build_props_config.py",
+    "$root_build_dir/Updater Packaging/signing/commands.py",
+    "$root_build_dir/Updater Packaging/sign_updater.py",
+    "$root_build_dir/chrome/updater/.install",
+    "$root_build_dir/UpdaterSetup",
+  ]
+  deps = [
+    ":updater_bundle",
+    ":updater_bundle_test",
+    ":updater_install_script",
+    "//chrome/updater/mac/installer:metainstaller",
+    "//chrome/updater/mac/signing",
+  ]
+}
diff --git a/chrome/updater/mac/install_from_archive.h b/chrome/updater/mac/install_from_archive.h
index b20e8fb..6126b172 100644
--- a/chrome/updater/mac/install_from_archive.h
+++ b/chrome/updater/mac/install_from_archive.h
@@ -11,6 +11,7 @@
 
 namespace base {
 class FilePath;
+class TimeDelta;
 class Version;
 }
 
@@ -58,7 +59,8 @@
     const UpdaterScope& scope,
     const base::Version& pv,
     const std::string& arguments,
-    const absl::optional<base::FilePath>& installer_data_file);
+    const absl::optional<base::FilePath>& installer_data_file,
+    const base::TimeDelta& timeout);
 
 }  // namespace updater
 
diff --git a/chrome/updater/mac/install_from_archive.mm b/chrome/updater/mac/install_from_archive.mm
index 498f510..909a1ed8 100644
--- a/chrome/updater/mac/install_from_archive.mm
+++ b/chrome/updater/mac/install_from_archive.mm
@@ -25,6 +25,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
+#include "base/time/time.h"
 #include "base/version.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/mac/mac_util.h"
@@ -126,6 +127,7 @@
                   const absl::optional<base::FilePath>& installer_data_file,
                   const UpdaterScope& scope,
                   const base::Version& pv,
+                  const base::TimeDelta& timeout,
                   const base::FilePath& unpacked_path) {
   if (!base::PathExists(unpacked_path)) {
     VLOG(1) << "File path (" << unpacked_path << ") does not exist.";
@@ -181,7 +183,8 @@
 
     int exit_code = 0;
     VLOG(1) << "Running " << command.GetCommandLineString();
-    if (!base::LaunchProcess(command, options).WaitForExit(&exit_code))
+    if (!base::LaunchProcess(command, options)
+             .WaitForExitWithTimeout(timeout, &exit_code))
       return static_cast<int>(InstallErrors::kExecutableWaitForExitFailed);
     if (exit_code != 0)
       return exit_code;
@@ -319,7 +322,8 @@
     const UpdaterScope& scope,
     const base::Version& pv,
     const std::string& arguments,
-    const absl::optional<base::FilePath>& installer_data_file) {
+    const absl::optional<base::FilePath>& installer_data_file,
+    const base::TimeDelta& timeout) {
   const std::map<std::string,
                  int (*)(const base::FilePath&,
                          base::OnceCallback<int(const base::FilePath&)>)>
@@ -332,8 +336,9 @@
     base::FilePath new_path = AlterFileExtension(file_path, entry.first);
     if (base::PathExists(new_path)) {
       return entry.second(
-          new_path, base::BindOnce(&RunExecutable, existence_checker_path, ap,
-                                   arguments, installer_data_file, scope, pv));
+          new_path,
+          base::BindOnce(&RunExecutable, existence_checker_path, ap, arguments,
+                         installer_data_file, scope, pv, timeout));
     }
   }
 
diff --git a/chrome/updater/mac/installer/BUILD.gn b/chrome/updater/mac/installer/BUILD.gn
index e1b1291..2ebb8af2 100644
--- a/chrome/updater/mac/installer/BUILD.gn
+++ b/chrome/updater/mac/installer/BUILD.gn
@@ -2,10 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/zip.gni")
 import("//chrome/updater/branding.gni")
-import("//chrome/updater/zip.gni")
 
-artifact_zip("updater_zip") {
+# This zip is a resource for the macOS metainstaller.
+zip("updater_zip") {
   output = "$target_gen_dir/updater.zip"
   inputs = [
     "$root_build_dir/${updater_product_full_name}.app/Contents/Info.plist",
diff --git a/chrome/updater/mac/setup/setup_unittest.mm b/chrome/updater/mac/setup/setup_unittest.mm
index 11fb173f..7b1d6f712 100644
--- a/chrome/updater/mac/setup/setup_unittest.mm
+++ b/chrome/updater/mac/setup/setup_unittest.mm
@@ -12,6 +12,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/test/task_environment.h"
+#include "base/time/time.h"
 #include "base/version.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/updater/mac/install_from_archive.h"
@@ -28,6 +29,7 @@
 constexpr char kTestBundleId[] = "com.install.test";
 constexpr char kTestDirName[] = "InstallerTestDir";
 constexpr char kUpdaterTestDMGName[] = "updater_setup_test_dmg.dmg";
+constexpr base::TimeDelta kTimeout = base::Seconds(45);
 
 void CreateTestApp(const base::FilePath& test_dir) {
   // Create file paths for each part of the app we want to create.
@@ -163,7 +165,7 @@
   ASSERT_TRUE(base::PathExists(dmg_file_path));
   ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, {},
                                         updater::UpdaterScope::kUser,
-                                        base::Version("0"), {}, {}),
+                                        base::Version("0"), {}, {}, kTimeout),
             0);
 }
 
@@ -173,9 +175,9 @@
   const base::FilePath dmg_file_path =
       GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
   ASSERT_TRUE(base::PathExists(dmg_file_path));
-  ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, {},
-                                        updater::UpdaterScope::kUser,
-                                        base::Version("0"), "arg2", {}),
+  ASSERT_NE(updater::InstallFromArchive(
+                dmg_file_path, {}, {}, updater::UpdaterScope::kUser,
+                base::Version("0"), "arg2", {}, kTimeout),
             0);
 }
 
@@ -192,7 +194,8 @@
 
   ASSERT_EQ(updater::InstallFromArchive(dmg_file_path, installed_app_path, {},
                                         updater::UpdaterScope::kUser,
-                                        base::Version(kTestAppVersion), {}, {}),
+                                        base::Version(kTestAppVersion), {}, {},
+                                        kTimeout),
             0);
 }
 
@@ -211,7 +214,7 @@
   std::string args = base::StrCat({kTestAppVersion, " arg1 arg2"});
   ASSERT_EQ(updater::InstallFromArchive(dmg_file_path, installed_app_path, {},
                                         updater::UpdaterScope::kUser,
-                                        base::Version("0"), args, {}),
+                                        base::Version("0"), args, {}, kTimeout),
             0);
 }
 
@@ -220,29 +223,32 @@
   ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
   test_dir = test_dir.Append("updater");
 
-  ASSERT_EQ(
-      updater::InstallFromArchive(
-          test_dir.Append("setup_test_envcheck").Append("marker.app"),
-          base::FilePath::FromASCII("xc_path"), "ap",
-          updater::UpdaterScope::kUser, base::Version("0"), "arg1 arg2", {}),
-      0);
+  ASSERT_EQ(updater::InstallFromArchive(
+                test_dir.Append("setup_test_envcheck").Append("marker.app"),
+                base::FilePath::FromASCII("xc_path"), "ap",
+                updater::UpdaterScope::kUser, base::Version("0"), "arg1 arg2",
+                {}, kTimeout),
+            0);
 
   ASSERT_EQ(
       updater::InstallFromArchive(
           test_dir.Append("setup_test_preinstallfailure").Append("marker.app"),
-          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {}),
+          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {},
+          kTimeout),
       1);
 
   ASSERT_EQ(
       updater::InstallFromArchive(
           test_dir.Append("setup_test_installfailure").Append("marker.app"), {},
-          {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {}),
+          {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {},
+          kTimeout),
       2);
 
   ASSERT_EQ(
       updater::InstallFromArchive(
           test_dir.Append("setup_test_postinstallfailure").Append("marker.app"),
-          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {}),
+          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {},
+          kTimeout),
       3);
 }
 
diff --git a/chrome/updater/mac/signing/BUILD.gn b/chrome/updater/mac/signing/BUILD.gn
index e87c732a..4e8d73d 100644
--- a/chrome/updater/mac/signing/BUILD.gn
+++ b/chrome/updater/mac/signing/BUILD.gn
@@ -54,7 +54,7 @@
 copy("copy_signing") {
   visibility = [ ":copies" ]
 
-  deps = [ ":sign_config" ]
+  public_deps = [ ":sign_config" ]
 
   adjusted_mac_signing_sources = mac_signing_sources - [
                                    "signing/chromium_config.py",
@@ -80,7 +80,7 @@
 copy("copies") {
   visibility = [ ":signing" ]
 
-  deps = [ ":copy_signing" ]
+  public_deps = [ ":copy_signing" ]
 
   sources = [ "//chrome/installer/mac/sign_chrome.py" ]
 
diff --git a/chrome/updater/run_all_unittests.cc b/chrome/updater/run_all_unittests.cc
index 925f47fc..d526c98 100644
--- a/chrome/updater/run_all_unittests.cc
+++ b/chrome/updater/run_all_unittests.cc
@@ -16,9 +16,12 @@
 #include "chrome/common/chrome_paths.h"
 
 #if BUILDFLAG(IS_WIN)
+#include <shlobj.h>
+
 #include <memory>
 
 #include "base/win/scoped_com_initializer.h"
+#include "chrome/installer/util/scoped_token_privilege.h"
 #include "chrome/updater/win/win_util.h"
 
 namespace {
@@ -88,6 +91,13 @@
     // Failing to disable COM exception handling is a critical error.
     CHECK(false) << "Failed to disable COM exception handling.";
   }
+
+  installer::ScopedTokenPrivilege token_se_debug(SE_DEBUG_NAME);
+  if (::IsUserAnAdmin() && !token_se_debug.is_enabled()) {
+    std::cerr << "Running as administrator but can't enable SE_DEBUG_NAME."
+              << std::endl;
+  }
+
 #endif
 
   base::TestSuite test_suite(argc, argv);
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h
index c3c8420d..ef8c4eb 100644
--- a/chrome/updater/test/integration_test_commands.h
+++ b/chrome/updater/test/integration_test_commands.h
@@ -81,6 +81,7 @@
       const std::string& command_id,
       const base::Value::List& parameters,
       int expected_exit_code) const = 0;
+  virtual void ExpectLegacyPolicyStatusSucceeds() const = 0;
   virtual void RunUninstallCmdLine() const = 0;
   virtual void SetUpTestService() const = 0;
   virtual void TearDownTestService() const = 0;
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc
index fbcb3031..ec75d15 100644
--- a/chrome/updater/test/integration_test_commands_system.cc
+++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -223,6 +223,10 @@
                base::NumberToString(expected_exit_code))});
   }
 
+  void ExpectLegacyPolicyStatusSucceeds() const override {
+    RunCommand("expect_legacy_policy_status_succeeds");
+  }
+
   void RunUninstallCmdLine() const override {
     RunCommand("run_uninstall_cmd_line");
   }
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc
index 9eb9ef6..2a5d765 100644
--- a/chrome/updater/test/integration_test_commands_user.cc
+++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -189,6 +189,10 @@
         updater_scope_, app_id, command_id, parameters, expected_exit_code);
   }
 
+  void ExpectLegacyPolicyStatusSucceeds() const override {
+    updater::test::ExpectLegacyPolicyStatusSucceeds(updater_scope_);
+  }
+
   void RunUninstallCmdLine() const override {
     updater::test::RunUninstallCmdLine(updater_scope_);
   }
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 05fe1d7..20bb2ea2 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -174,6 +174,10 @@
         app_id, command_id, parameters, expected_exit_code);
   }
 
+  void ExpectLegacyPolicyStatusSucceeds() {
+    test_commands_->ExpectLegacyPolicyStatusSucceeds();
+  }
+
   void RunUninstallCmdLine() { test_commands_->RunUninstallCmdLine(); }
 #endif  // BUILDFLAG(IS_WIN)
 
@@ -605,6 +609,22 @@
   Uninstall();
 }
 
+TEST_F(IntegrationTest, LegacyPolicyStatus) {
+  ScopedServer test_server(test_commands_);
+  Install();
+
+  const std::string kAppId("test");
+  InstallApp(kAppId);
+  base::Version v1("1");
+  ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), v1);
+  RunWake(0);
+  ExpectAppVersion(kAppId, v1);
+
+  ExpectLegacyPolicyStatusSucceeds();
+
+  Uninstall();
+}
+
 TEST_F(IntegrationTest, UninstallCmdLine) {
   Install();
   ExpectInstalled();
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc
index 59498b1..eb2f9de 100644
--- a/chrome/updater/test/integration_tests_helper.cc
+++ b/chrome/updater/test/integration_tests_helper.cc
@@ -264,6 +264,8 @@
                  WithSwitch("app_id",
                             WithSystemScope(
                                 Wrap(&ExpectLegacyAppCommandWebSucceeds))))))},
+    {"expect_legacy_policy_status_succeeds",
+     WithSystemScope(Wrap(&ExpectLegacyPolicyStatusSucceeds))},
     {"run_uninstall_cmd_line", WithSystemScope(Wrap(&RunUninstallCmdLine))},
 #endif  // BUILDFLAG(IS_WIN)
     {"expect_version_active",
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h
index cf4aa22d..87b4a64 100644
--- a/chrome/updater/test/integration_tests_impl.h
+++ b/chrome/updater/test/integration_tests_impl.h
@@ -175,6 +175,7 @@
                                        const std::string& command_id,
                                        const base::Value::List& parameters,
                                        int expected_exit_code);
+void ExpectLegacyPolicyStatusSucceeds(UpdaterScope scope);
 void RunTestServiceCommand(const std::string& sub_command);
 
 // Calls a function defined in test/service/win/rpc_client.py.
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index fa719f6..388e33e 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -656,18 +656,6 @@
     Microsoft::WRL::ComPtr<IDispatch> dispatch;
     ASSERT_HRESULT_SUCCEEDED(google_update->createAppBundleWeb(&dispatch));
     EXPECT_HRESULT_SUCCEEDED(dispatch.As(&app_bundle));
-
-    Microsoft::WRL::ComPtr<IUnknown> policy_status_server;
-    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
-        scope == UpdaterScope::kSystem ? __uuidof(PolicyStatusSystemClass)
-                                       : __uuidof(PolicyStatusUserClass),
-        nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&policy_status_server)));
-    Microsoft::WRL::ComPtr<IPolicyStatus2> policy_status2;
-    ASSERT_HRESULT_SUCCEEDED(policy_status_server.As(&policy_status2));
-    base::win::ScopedBstr updater_version;
-    ASSERT_HRESULT_SUCCEEDED(
-        policy_status2->get_updaterVersion(updater_version.Receive()));
-    EXPECT_STREQ(updater_version.Get(), kUpdaterVersionUtf16);
   }
 
   // IUpdaterInternal.
@@ -1012,6 +1000,24 @@
   DeleteAppClientKey(scope, appid);
 }
 
+void ExpectLegacyPolicyStatusSucceeds(UpdaterScope scope) {
+  Microsoft::WRL::ComPtr<IUnknown> policy_status_server;
+  ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(
+      scope == UpdaterScope::kSystem ? __uuidof(PolicyStatusSystemClass)
+                                     : __uuidof(PolicyStatusUserClass),
+      nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&policy_status_server)));
+  Microsoft::WRL::ComPtr<IPolicyStatus2> policy_status2;
+  ASSERT_HRESULT_SUCCEEDED(policy_status_server.As(&policy_status2));
+  base::win::ScopedBstr updater_version;
+  ASSERT_HRESULT_SUCCEEDED(
+      policy_status2->get_updaterVersion(updater_version.Receive()));
+  EXPECT_STREQ(updater_version.Get(), kUpdaterVersionUtf16);
+
+  DATE last_checked = 0;
+  EXPECT_HRESULT_SUCCEEDED(policy_status2->get_lastCheckedTime(&last_checked));
+  EXPECT_GT(static_cast<int>(last_checked), 0);
+}
+
 int RunVPythonCommand(const base::CommandLine& command_line) {
   base::CommandLine python_command = command_line;
   python_command.PrependWrapper(FILE_PATH_LITERAL("vpython3.bat"));
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc
index d3fd4196..8fba9827 100644
--- a/chrome/updater/update_service_impl.cc
+++ b/chrome/updater/update_service_impl.cc
@@ -537,6 +537,7 @@
             return RunApplicationInstaller(
                 app_info, installer_path, install_args,
                 WriteInstallerDataToTempFile(temp_dir.GetPath(), install_data),
+                kWaitForAppInstaller,
                 base::BindRepeating(
                     [](StateChangeCallback state_update,
                        const std::string& app_id, int progress) {
diff --git a/chrome/updater/updater_unittest.cc b/chrome/updater/updater_unittest.cc
index b9098af..e1e0a90 100644
--- a/chrome/updater/updater_unittest.cc
+++ b/chrome/updater/updater_unittest.cc
@@ -18,7 +18,11 @@
 #endif  // BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_WIN)
+#include <shlobj.h>
+
 #include "base/file_version_info_win.h"
+#include "base/win/access_token.h"
+#include "base/win/windows_types.h"
 #endif
 
 namespace updater {
@@ -61,6 +65,26 @@
 
   EXPECT_EQ(version_info->original_filename(), executable_test.AsUTF16Unsafe());
 }
-#endif
+
+// Checks that the unit test has the SE_DEBUG_NAME privilege when the process is
+// running as Administrator.
+TEST(UpdaterTest, UpdaterTestDebugPrivilege) {
+  if (!::IsUserAnAdmin())
+    return;
+
+  LUID luid = {0};
+  ASSERT_TRUE(::LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, &luid));
+
+  CHROME_LUID chrome_luid = {0};
+  chrome_luid.LowPart = luid.LowPart;
+  chrome_luid.HighPart = luid.HighPart;
+  const base::win::AccessToken::Privilege priv(chrome_luid,
+                                               SE_PRIVILEGE_ENABLED);
+
+  EXPECT_EQ(priv.GetName(), SE_DEBUG_NAME);
+  EXPECT_EQ(priv.GetAttributes(), DWORD{SE_PRIVILEGE_ENABLED});
+  EXPECT_TRUE(priv.IsEnabled());
+}
+#endif  // IS_WIN
 
 }  // namespace updater
diff --git a/chrome/updater/win/installer_api.cc b/chrome/updater/win/installer_api.cc
index 59d97a7..46d7ef4 100644
--- a/chrome/updater/win/installer_api.cc
+++ b/chrome/updater/win/installer_api.cc
@@ -19,6 +19,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/win/registry.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/enum_traits.h"
@@ -319,6 +320,7 @@
     const base::FilePath& app_installer,
     const std::string& arguments,
     const absl::optional<base::FilePath>& installer_data_file,
+    const base::TimeDelta& timeout,
     InstallProgressCallback progress_callback) {
   if (!base::PathExists(app_installer))
     return AppInstallerResult(kErrorMissingRunableFile);
@@ -351,7 +353,7 @@
   }
 
   int exit_code = -1;
-  const auto time_begin = base::Time::NowFromSystemTime();
+  const base::ElapsedTimer timer;
   do {
     bool wait_result = process.WaitForExitWithTimeout(
         base::Seconds(kWaitForInstallerProgressSec), &exit_code);
@@ -362,8 +364,7 @@
       VLOG(1) << "Installer exit code " << exit_code;
       break;
     }
-  } while (base::Time::NowFromSystemTime() - time_begin <=
-           base::Seconds(kWaitForAppInstallerSec));
+  } while (timer.Elapsed() < timeout);
 
   return MakeInstallerResult(
       GetInstallerOutcome(app_info.scope, app_info.app_id), exit_code);
diff --git a/chromecast/metrics/BUILD.gn b/chromecast/metrics/BUILD.gn
index ef4c6fd..a13dd7ca 100644
--- a/chromecast/metrics/BUILD.gn
+++ b/chromecast/metrics/BUILD.gn
@@ -24,10 +24,6 @@
     "//components/metrics:net",
     "//components/prefs",
     "//components/variations:variations",
-
-    # TODO(crbug.com/1241702): Clean up version_info when the Variations Safe
-    # Mode experiment is over.
-    "//components/version_info",
     "//services/network/public/cpp",
   ]
 }
diff --git a/chromecast/metrics/DEPS b/chromecast/metrics/DEPS
index 3526e78..ebfe7384 100644
--- a/chromecast/metrics/DEPS
+++ b/chromecast/metrics/DEPS
@@ -2,7 +2,6 @@
   "+components/metrics",
   "+components/prefs",
   "+components/variations/synthetic_trial_registry.h",
-  "+components/version_info",
   "+net/base",
   "+services/network/public",
   "+third_party/metrics_proto",
diff --git a/chromecast/metrics/cast_metrics_service_client.cc b/chromecast/metrics/cast_metrics_service_client.cc
index 89698e3..3747896 100644
--- a/chromecast/metrics/cast_metrics_service_client.cc
+++ b/chromecast/metrics/cast_metrics_service_client.cc
@@ -31,7 +31,6 @@
 #include "components/metrics/url_constants.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/version_info/channel.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 #if BUILDFLAG(IS_ANDROID)
@@ -316,7 +315,7 @@
       // Pass an empty file path since Chromecast does not use the Variations
       // framework.
       /*user_data_dir=*/base::FilePath(),
-      ::metrics::StartupVisibility::kUnknown, version_info::Channel::UNKNOWN,
+      ::metrics::StartupVisibility::kUnknown,
       base::BindRepeating(&CastMetricsServiceClient::StoreClientInfo,
                           base::Unretained(this)),
       base::BindRepeating(&CastMetricsServiceClient::LoadClientInfo,
diff --git a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
index 101ba39..dc4768f 100644
--- a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
+++ b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.cc
@@ -143,9 +143,10 @@
     return false;
   }
   *entry =
-      MountEntry(CrosDisksMountErrorToChromeMountError(
+      MountEntry{CrosDisksMountErrorToChromeMountError(
                      static_cast<cros_disks::MountErrorType>(error_code)),
-                 source_path, static_cast<MountType>(mount_type), mount_path);
+                 std::move(source_path), static_cast<MountType>(mount_type),
+                 std::move(mount_path)};
   return true;
 }
 
@@ -447,7 +448,7 @@
         std::move(error_callback).Run();
         return;
       }
-      entries.push_back(entry);
+      entries.push_back(std::move(entry));
     }
     std::move(callback).Run(entries);
   }
@@ -489,15 +490,15 @@
     }
 
     UMA_HISTOGRAM_ENUMERATION("CrosDisksClient.MountCompletedError",
-                              entry.error_code(), MountError::kCount);
+                              entry.error_code, MountError::kCount);
     // Flatten MountType and MountError into a single dimension.
     constexpr int kMaxMountErrors = 100;
     static_assert(static_cast<int>(MountError::kCount) <= kMaxMountErrors,
                   "CrosDisksClient.MountErrorMountType histogram must be "
                   "updated.");
     const int type_and_error =
-        (static_cast<int>(entry.mount_type()) * kMaxMountErrors) +
-        static_cast<int>(entry.error_code());
+        (static_cast<int>(entry.mount_type) * kMaxMountErrors) +
+        static_cast<int>(entry.error_code);
     base::UmaHistogramSparse("CrosDisksClient.MountErrorMountType",
                              type_and_error);
     for (auto& observer : observer_list_)
diff --git a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
index 2066b8f..9d8443c 100644
--- a/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
+++ b/chromeos/ash/components/dbus/cros_disks/cros_disks_client.h
@@ -277,30 +277,11 @@
 };
 
 // A struct to represent information about a mount point sent from cros-disks.
-struct COMPONENT_EXPORT(ASH_DBUS_CROS_DISKS) MountEntry {
- public:
-  MountEntry()
-      : error_code_(MountError::kUnknown), mount_type_(MountType::kInvalid) {}
-
-  MountEntry(MountError error_code,
-             const std::string& source_path,
-             MountType mount_type,
-             const std::string& mount_path)
-      : error_code_(error_code),
-        source_path_(source_path),
-        mount_type_(mount_type),
-        mount_path_(mount_path) {}
-
-  MountError error_code() const { return error_code_; }
-  const std::string& source_path() const { return source_path_; }
-  MountType mount_type() const { return mount_type_; }
-  const std::string& mount_path() const { return mount_path_; }
-
- private:
-  MountError error_code_;
-  std::string source_path_;
-  MountType mount_type_;
-  std::string mount_path_;
+struct MountEntry {
+  MountError error_code = MountError::kUnknown;
+  std::string source_path;
+  MountType mount_type = MountType::kInvalid;
+  std::string mount_path;
 };
 
 // A class to make the actual DBus calls for cros-disks service.
diff --git a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
index 67a771c..d744809 100644
--- a/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
+++ b/chromeos/ash/components/dbus/cros_disks/fake_cros_disks_client.cc
@@ -230,7 +230,7 @@
                                                const std::string& mount_path) {
   for (auto& observer : observer_list_) {
     observer.OnMountCompleted(
-        MountEntry(error_code, source_path, mount_type, mount_path));
+        {error_code, source_path, mount_type, mount_path});
   }
 }
 
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index d77a97b..086baf86 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -243,6 +243,9 @@
 
   # https://crbug.com/1346149
   "apps.Sharesheet",
+
+  # b/241122961
+  "policy.BlockThirdPartyCookies",
 ]
 
 # To create filters to be used on specific builders add them like this:
diff --git a/components/autofill/content/browser/autofill_internals_log_router_unittest.cc b/components/autofill/content/browser/autofill_internals_log_router_unittest.cc
index 02a5e490..65bdc6a 100644
--- a/components/autofill/content/browser/autofill_internals_log_router_unittest.cc
+++ b/components/autofill/content/browser/autofill_internals_log_router_unittest.cc
@@ -23,7 +23,7 @@
  public:
   MockLogReceiver() {}
 
-  MOCK_METHOD(void, LogEntry, (const base::Value&), (override));
+  MOCK_METHOD(void, LogEntry, (const base::Value::Dict&), (override));
 };
 
 }  // namespace
@@ -55,7 +55,8 @@
   ASSERT_TRUE(log_router);
   log_router->RegisterReceiver(&receiver);
 
-  base::Value log_entry = autofill::LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry =
+      autofill::LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver, LogEntry(testing::Eq(testing::ByRef(log_entry))))
       .Times(1);
   log_router->ProcessLog(kTestText);
diff --git a/components/autofill/content/browser/content_autofill_driver_factory.cc b/components/autofill/content/browser/content_autofill_driver_factory.cc
index 42a4b7fc..85785d4 100644
--- a/components/autofill/content/browser/content_autofill_driver_factory.cc
+++ b/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -160,8 +160,8 @@
   ContentAutofillDriver* driver = it->second.get();
   DCHECK(driver);
 
-  if (render_frame_host->GetLifecycleState() !=
-          content::RenderFrameHost::LifecycleState::kPrerendering &&
+  if (!render_frame_host->IsInLifecycleState(
+          content::RenderFrameHost::LifecycleState::kPrerendering) &&
       driver->autofill_manager()) {
     driver->autofill_manager()->ReportAutofillWebOTPMetrics(
         render_frame_host->DocumentUsedWebOTP());
@@ -174,8 +174,8 @@
   // and therefore won't close the popup.
   bool is_iframe = !driver->IsInAnyMainFrame();
   if (is_iframe && router_.last_queried_source() == driver) {
-    DCHECK_NE(content::RenderFrameHost::LifecycleState::kPrerendering,
-              render_frame_host->GetLifecycleState());
+    DCHECK(!render_frame_host->IsInLifecycleState(
+        content::RenderFrameHost::LifecycleState::kPrerendering));
     router_.HidePopup(driver);
   }
 
diff --git a/components/autofill/core/browser/logging/log_buffer_submitter.cc b/components/autofill/core/browser/logging/log_buffer_submitter.cc
index 1418725..a084333c 100644
--- a/components/autofill/core/browser/logging/log_buffer_submitter.cc
+++ b/components/autofill/core/browser/logging/log_buffer_submitter.cc
@@ -29,12 +29,12 @@
 }
 
 LogBufferSubmitter::~LogBufferSubmitter() {
-  if (!destruct_with_logging_)
+  if (!destruct_with_logging_ || !destination_)
     return;
-  base::Value message = buffer_.RetrieveResult();
-  if (!destination_ || message.is_none())
+  absl::optional<base::Value::Dict> message = buffer_.RetrieveResult();
+  if (!message)
     return;
-  destination_->ProcessLog(message);
+  destination_->ProcessLog(*message);
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc b/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
index 9e86849..b5f99a87 100644
--- a/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
+++ b/components/autofill/core/browser/logging/log_buffer_submitter_unittest.cc
@@ -20,13 +20,13 @@
 
 class MockLogReceiver : public LogReceiver {
  public:
-  MOCK_METHOD(void, LogEntry, (const base::Value&), (override));
+  MOCK_METHOD(void, LogEntry, (const base::Value::Dict&), (override));
 };
 
 TEST(LogBufferSubmitter, VerifySubmissionOnDestruction) {
   LogBuffer buffer;
   buffer << 42;
-  base::Value expected = buffer.RetrieveResult();
+  absl::optional<base::Value::Dict> expected = buffer.RetrieveResult();
 
   MockLogReceiver receiver;
   LogRouter router;
@@ -34,7 +34,7 @@
   std::unique_ptr<LogManager> log_manager =
       LogManager::Create(&router, base::NullCallback());
 
-  EXPECT_CALL(receiver, LogEntry(testing::Eq(testing::ByRef(expected))));
+  EXPECT_CALL(receiver, LogEntry(testing::Eq(testing::ByRef(*expected))));
   log_manager->Log() << 42;
   log_manager.reset();
   router.UnregisterReceiver(&receiver);
diff --git a/components/autofill/core/browser/logging/log_manager.cc b/components/autofill/core/browser/logging/log_manager.cc
index 868608f..fd43d0a 100644
--- a/components/autofill/core/browser/logging/log_manager.cc
+++ b/components/autofill/core/browser/logging/log_manager.cc
@@ -25,7 +25,7 @@
   void OnLogRouterAvailabilityChanged(bool router_can_be_used) override;
   void SetSuspended(bool suspended) override;
   void LogTextMessage(const std::string& text) const override;
-  void LogEntry(const base::Value& entry) const override;
+  void LogEntry(const base::Value::Dict& entry) const override;
   bool IsLoggingActive() const override;
   LogBufferSubmitter Log() override;
 
@@ -83,7 +83,7 @@
   log_router_->ProcessLog(text);
 }
 
-void LogManagerImpl::LogEntry(const base::Value& entry) const {
+void LogManagerImpl::LogEntry(const base::Value::Dict& entry) const {
   if (!IsLoggingActive())
     return;
   log_router_->ProcessLog(entry);
diff --git a/components/autofill/core/browser/logging/log_manager.h b/components/autofill/core/browser/logging/log_manager.h
index d2b0128..e34e8c9 100644
--- a/components/autofill/core/browser/logging/log_manager.h
+++ b/components/autofill/core/browser/logging/log_manager.h
@@ -43,7 +43,7 @@
 
   // Forward a DOM structured log entry to the LogRouter (if registered with
   // one).
-  virtual void LogEntry(const base::Value& entry) const = 0;
+  virtual void LogEntry(const base::Value::Dict& entry) const = 0;
 
   // Returns true if logs recorded via LogTextMessage will be displayed, and
   // false otherwise.
diff --git a/components/autofill/core/browser/logging/log_manager_unittest.cc b/components/autofill/core/browser/logging/log_manager_unittest.cc
index 0fbb808..3d13dff 100644
--- a/components/autofill/core/browser/logging/log_manager_unittest.cc
+++ b/components/autofill/core/browser/logging/log_manager_unittest.cc
@@ -26,7 +26,7 @@
   MockLogReceiver(const MockLogReceiver&) = delete;
   MockLogReceiver& operator=(const MockLogReceiver&) = delete;
 
-  MOCK_METHOD(void, LogEntry, (const base::Value&), (override));
+  MOCK_METHOD(void, LogEntry, (const base::Value::Dict&), (override));
 };
 
 class MockNotifiedObject {
@@ -75,7 +75,7 @@
   router_.RegisterReceiver(&receiver_);
   EXPECT_TRUE(manager_->IsLoggingActive());
   // After attaching the logger, text should be passed.
-  base::Value log_entry = LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry = LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver_, LogEntry(testing::Eq(testing::ByRef(log_entry))));
   manager_->LogTextMessage(kTestText);
   EXPECT_CALL(notified_object_, NotifyAboutLoggingActivity());
diff --git a/components/autofill/core/browser/logging/log_receiver.h b/components/autofill/core/browser/logging/log_receiver.h
index e984c33..ddc78ae 100644
--- a/components/autofill/core/browser/logging/log_receiver.h
+++ b/components/autofill/core/browser/logging/log_receiver.h
@@ -20,7 +20,7 @@
 
   virtual ~LogReceiver() {}
 
-  virtual void LogEntry(const base::Value& entry) = 0;
+  virtual void LogEntry(const base::Value::Dict& entry) = 0;
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/logging/log_router.cc b/components/autofill/core/browser/logging/log_router.cc
index cca03ca7..1e45079 100644
--- a/components/autofill/core/browser/logging/log_router.cc
+++ b/components/autofill/core/browser/logging/log_router.cc
@@ -18,7 +18,7 @@
 LogRouter::~LogRouter() = default;
 
 // static
-base::Value LogRouter::CreateEntryForText(const std::string& text) {
+base::Value::Dict LogRouter::CreateEntryForText(const std::string& text) {
   LogBuffer buffer(LogBuffer::IsActive(true));
   buffer << Tag{"div"};
   for (const auto& line : base::SplitStringPiece(
@@ -26,14 +26,14 @@
     buffer << line << Br{};
   }
   buffer << CTag{};
-  return buffer.RetrieveResult();
+  return *buffer.RetrieveResult();
 }
 
 void LogRouter::ProcessLog(const std::string& text) {
   ProcessLog(CreateEntryForText(text));
 }
 
-void LogRouter::ProcessLog(const base::Value& node) {
+void LogRouter::ProcessLog(const base::Value::Dict& node) {
   // This may not be called when there are no receivers (i.e., the router is
   // inactive), because in that case the logs cannot be displayed.
   DCHECK(!receivers_.empty());
diff --git a/components/autofill/core/browser/logging/log_router.h b/components/autofill/core/browser/logging/log_router.h
index 2dfe481..b335bd3 100644
--- a/components/autofill/core/browser/logging/log_router.h
+++ b/components/autofill/core/browser/logging/log_router.h
@@ -32,11 +32,11 @@
   ~LogRouter() override;
 
   // Returns a JSON entry that can be fed into the logger.
-  static base::Value CreateEntryForText(const std::string& text);
+  static base::Value::Dict CreateEntryForText(const std::string& text);
 
   // Passes logs to the router. Only call when there are receivers registered.
   void ProcessLog(const std::string& text);
-  void ProcessLog(const base::Value& node);
+  void ProcessLog(const base::Value::Dict& node);
 
   // All four (Unr|R)egister* methods below are safe to call from the
   // constructor of the registered object, because they do not call that object,
diff --git a/components/autofill/core/browser/logging/log_router_unittest.cc b/components/autofill/core/browser/logging/log_router_unittest.cc
index 96cb453a..1e54649 100644
--- a/components/autofill/core/browser/logging/log_router_unittest.cc
+++ b/components/autofill/core/browser/logging/log_router_unittest.cc
@@ -25,7 +25,7 @@
   MockLogReceiver(const MockLogReceiver&) = delete;
   MockLogReceiver& operator=(const MockLogReceiver&) = delete;
 
-  MOCK_METHOD(void, LogEntry, (const base::Value&), (override));
+  MOCK_METHOD(void, LogEntry, (const base::Value::Dict&), (override));
 };
 
 class MockLogManager : public StubLogManager {
@@ -50,7 +50,7 @@
 TEST_F(LogRouterTest, ProcessLog_OneReceiver) {
   LogRouter router;
   router.RegisterReceiver(&receiver_);
-  base::Value log_entry = LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry = LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver_, LogEntry(testing::Eq(testing::ByRef(log_entry))))
       .Times(1);
   router.ProcessLog(kTestText);
@@ -63,7 +63,7 @@
   router.RegisterReceiver(&receiver2_);
 
   // Check that both receivers get log updates.
-  base::Value log_entry = LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry = LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver_, LogEntry(testing::Eq(testing::ByRef(log_entry))))
       .Times(1);
   EXPECT_CALL(receiver2_, LogEntry(testing::Eq(testing::ByRef(log_entry))))
@@ -81,7 +81,7 @@
   // Check that no logs are passed to an unregistered receiver.
   router.UnregisterReceiver(&receiver_);
   EXPECT_CALL(receiver_, LogEntry(_)).Times(0);
-  base::Value log_entry = LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry = LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver2_, LogEntry(testing::Eq(testing::ByRef(log_entry))))
       .Times(1);
   router.ProcessLog(kTestText);
diff --git a/components/autofill/core/browser/logging/stub_log_manager.cc b/components/autofill/core/browser/logging/stub_log_manager.cc
index fc87ecbb..00a6ad1 100644
--- a/components/autofill/core/browser/logging/stub_log_manager.cc
+++ b/components/autofill/core/browser/logging/stub_log_manager.cc
@@ -12,7 +12,7 @@
 
 void StubLogManager::LogTextMessage(const std::string& text) const {}
 
-void StubLogManager::LogEntry(const base::Value& entry) const {}
+void StubLogManager::LogEntry(const base::Value::Dict& entry) const {}
 
 bool StubLogManager::IsLoggingActive() const {
   return false;
diff --git a/components/autofill/core/browser/logging/stub_log_manager.h b/components/autofill/core/browser/logging/stub_log_manager.h
index 1cd8bb51..949bfe2 100644
--- a/components/autofill/core/browser/logging/stub_log_manager.h
+++ b/components/autofill/core/browser/logging/stub_log_manager.h
@@ -26,7 +26,7 @@
   void OnLogRouterAvailabilityChanged(bool router_can_be_used) override;
   void SetSuspended(bool suspended) override;
   void LogTextMessage(const std::string& text) const override;
-  void LogEntry(const base::Value& entry) const override;
+  void LogEntry(const base::Value::Dict& entry) const override;
   bool IsLoggingActive() const override;
   LogBufferSubmitter Log() override;
 };
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index fe55bad..bd1f9ed 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -343,7 +343,7 @@
 // shown. This is to prevent double clicks accidentally accepting suggestions.
 // TODO(crbug/1279268): Remove once launched.
 const base::Feature kAutofillIgnoreEarlyClicksOnPopup{
-    "AutofillIgnoreEarlyClicksOnPopup", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AutofillIgnoreEarlyClicksOnPopup", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // The duration for which clicks on the just-shown Autofill popup should be
 // ignored if AutofillIgnoreEarlyClicksOnPopup is enabled.
diff --git a/components/autofill/core/common/autofill_internals/log_message_unittest.cc b/components/autofill/core/common/autofill_internals/log_message_unittest.cc
index 2d4f225..f6fbb63 100644
--- a/components/autofill/core/common/autofill_internals/log_message_unittest.cc
+++ b/components/autofill/core/common/autofill_internals/log_message_unittest.cc
@@ -14,7 +14,7 @@
   LogBuffer buffer;
   buffer << LogMessage::kParsedForms;
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"attributes":{"class":"log-message","message":"ParsedForms"},)"
             R"("children":[{"type":"text","value":"Parsed forms:"}],)"
             R"("type":"element","value":"div"})",
diff --git a/components/autofill/core/common/autofill_internals/logging_scope_unittest.cc b/components/autofill/core/common/autofill_internals/logging_scope_unittest.cc
index 16ffe96f..25c6dfdc 100644
--- a/components/autofill/core/common/autofill_internals/logging_scope_unittest.cc
+++ b/components/autofill/core/common/autofill_internals/logging_scope_unittest.cc
@@ -14,7 +14,7 @@
   LogBuffer buffer;
   buffer << LoggingScope::kContext;
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"attributes":{"class":"log-entry","scope":"Context"},)"
             R"("type":"element","value":"div"})",
             json);
diff --git a/components/autofill/core/common/logging/log_buffer.cc b/components/autofill/core/common/logging/log_buffer.cc
index ef3fffd..c8d955c 100644
--- a/components/autofill/core/common/logging/log_buffer.cc
+++ b/components/autofill/core/common/logging/log_buffer.cc
@@ -91,7 +91,7 @@
 LogBuffer& LogBuffer::operator=(LogBuffer&& other) = default;
 LogBuffer::~LogBuffer() = default;
 
-base::Value LogBuffer::RetrieveResult() {
+absl::optional<base::Value::Dict> LogBuffer::RetrieveResult() {
   // The buffer should always start with a fragment.
   DCHECK(buffer_.size() >= 1);
 
@@ -101,15 +101,16 @@
 
   auto* children = buffer_[0].FindList("children");
   if (!children || children->empty())
-    return base::Value();
+    return absl::nullopt;
 
   // If the fragment has a single child, remove it from |children| and return
   // that directly.
   if (children->size() == 1) {
-    return std::move(std::move(*children).back());
+    return absl::optional<base::Value::Dict>(
+        std::move((*children).back().GetDict()));
   }
 
-  return base::Value(std::exchange(buffer_.back(), CreateEmptyFragment()));
+  return std::exchange(buffer_.back(), CreateEmptyFragment());
 }
 
 LogBuffer& operator<<(LogBuffer& buf, Tag&& tag) {
@@ -188,13 +189,12 @@
   if (!buf.active())
     return buf;
 
-  base::Value node_to_add(buffer.RetrieveResult());
-  if (node_to_add.is_none())
+  absl::optional<base::Value::Dict> node_to_add = buffer.RetrieveResult();
+  if (!node_to_add)
     return buf;
 
-  base::Value::Dict* node_to_add_dict = &node_to_add.GetDict();
-  if (IsFragment(*node_to_add_dict)) {
-    auto* children = node_to_add_dict->FindList("children");
+  if (IsFragment(*node_to_add)) {
+    auto* children = node_to_add->FindList("children");
     if (!children)
       return buf;
     for (auto& child : *children) {
@@ -203,7 +203,7 @@
     }
     return buf;
   }
-  AppendChildToLastNode(&buf.buffer_, std::move(*node_to_add_dict));
+  AppendChildToLastNode(&buf.buffer_, std::move(*node_to_add));
   return buf;
 }
 
diff --git a/components/autofill/core/common/logging/log_buffer.h b/components/autofill/core/common/logging/log_buffer.h
index e39db5d..c1f8e28 100644
--- a/components/autofill/core/common/logging/log_buffer.h
+++ b/components/autofill/core/common/logging/log_buffer.h
@@ -110,8 +110,8 @@
   LogBuffer(const LogBuffer& other) = delete;
   LogBuffer& operator=(const LogBuffer& other) = delete;
 
-  // Returns the contents of the buffer and empties it.
-  base::Value RetrieveResult();
+  // Returns the contents of the buffer if any and empties it.
+  absl::optional<base::Value::Dict> RetrieveResult();
 
   // Returns whether an active WebUI is listening. If false, the buffer may
   // not do any logging.
diff --git a/components/autofill/core/common/logging/log_buffer_unittest.cc b/components/autofill/core/common/logging/log_buffer_unittest.cc
index b1ce238..3083fdd 100644
--- a/components/autofill/core/common/logging/log_buffer_unittest.cc
+++ b/components/autofill/core/common/logging/log_buffer_unittest.cc
@@ -17,7 +17,7 @@
   LogBuffer buffer;
   buffer << "<foo><!--\"";
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   // JSON takes care of serializing the <, we don't want &lt; as that would then
   // be escaped twice.
   EXPECT_EQ(R"({"type":"text","value":"\u003Cfoo>\u003C!--\""})", json);
@@ -27,7 +27,7 @@
   LogBuffer buffer;
   buffer << u"<foo><!--\"";
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   // JSON takes care of serializing the <, we don't want &lt; as that would then
   // be escaped twice.
   EXPECT_EQ(R"({"type":"text","value":"\u003Cfoo>\u003C!--\""})", json);
@@ -37,7 +37,7 @@
   LogBuffer buffer;
   buffer << 42;
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"type":"text","value":"42"})", json);
 }
 
@@ -45,21 +45,21 @@
   LogBuffer buffer;
   buffer << GURL("https://user:pw@www.example.com:80/foo?bar=1#foo");
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   // Verify that the url gets scrubbed.
   EXPECT_EQ(R"({"type":"text","value":"https://www.example.com:80/"})", json);
 }
 
 TEST(LogBuffer, Empty) {
   LogBuffer buffer;
-  EXPECT_EQ(base::Value(), buffer.RetrieveResult());
+  EXPECT_FALSE(buffer.RetrieveResult());
 }
 
 TEST(LogBuffer, UnclosedTag) {
   LogBuffer buffer;
   buffer << Tag{"foo"};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"type":"element","value":"foo"})", json);
 }
 
@@ -67,7 +67,7 @@
   LogBuffer buffer;
   buffer << Tag{"foo"} << CTag{};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"type":"element","value":"foo"})", json);
 }
 
@@ -75,7 +75,7 @@
   LogBuffer buffer;
   buffer << Tag{"foo"} << Tag{"bar"} << CTag{} << CTag{};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"element","value":"bar"}],)"
             R"("type":"element","value":"foo"})",
             json);
@@ -85,7 +85,7 @@
   LogBuffer buffer;
   buffer << Tag{"foo"} << Tag{"bar"} << CTag{} << CTag{} << CTag{};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"element","value":"bar"}],)"
             R"("type":"element","value":"foo"})",
             json);
@@ -95,7 +95,7 @@
   LogBuffer buffer;
   buffer << Tag{"foo"} << Tag{"bar"};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"element","value":"bar"}],)"
             R"("type":"element","value":"foo"})",
             json);
@@ -106,7 +106,7 @@
   buffer << Tag{"foo"} << Tag{"bar"} << Attrib{"b1", "1"} << Attrib{"b2", "2"}
          << CTag{} << Attrib{"f1", "1"};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(
       R"({"attributes":{"f1":"1"},"children":[)"
       R"({"attributes":{"b1":"1","b2":"2"},"type":"element","value":"bar"})"
@@ -118,7 +118,7 @@
   LogBuffer buffer;
   buffer << Tag{"div"} << "foo" << Br{} << "bar" << CTag{};
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"text","value":"foo"},)"
             R"({"type":"element","value":"br"},{"type":"text","value":"bar"}],)"
             R"("type":"element","value":"div"})",
@@ -130,7 +130,7 @@
   buffer << Tag{"div"} << "foo"
          << "bar";
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"text","value":"foobar"}],)"
             R"("type":"element","value":"div"})",
             json);
@@ -156,7 +156,7 @@
   SampleObject o{42, "foobar<!--"};
   buffer << o;
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[)"                                      // table
             /**/ R"({"children":[)"                                 // tr
             /****/ R"({"children":[{"type":"text","value":"x"}],)"  // td
@@ -185,14 +185,14 @@
   actual << Tr{} << Attrib{"class", "awesome"} << "Foo"
          << "Bar";
   actual << CTag{"table"};
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, CreateFragment) {
   LogBuffer buffer;
   buffer << "foo" << Br{} << "bar";
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"text","value":"foo"},)"
             R"({"type":"element","value":"br"},{"type":"text","value":"bar"}],)"
             R"("type":"fragment"})",
@@ -205,7 +205,7 @@
   LogBuffer buffer;
   buffer << std::move(tmp_buffer);
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"children":[{"type":"text","value":"foo"},)"
             R"({"type":"element","value":"br"},{"type":"text","value":"bar"}],)"
             R"("type":"fragment"})",
@@ -218,7 +218,7 @@
   LogBuffer buffer;
   buffer << std::move(tmp_buffer);
   std::string json;
-  EXPECT_TRUE(base::JSONWriter::Write(buffer.RetrieveResult(), &json));
+  EXPECT_TRUE(base::JSONWriter::Write(*buffer.RetrieveResult(), &json));
   EXPECT_EQ(R"({"type":"text","value":"foo"})", json);
 }
 
@@ -227,7 +227,7 @@
   expected << "foo" << Tag{"b"} << "bar" << CTag{"b"} << "baz";
   LogBuffer actual;
   actual << HighlightValue("foobarbaz", "bar");
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, HighlightAtStart) {
@@ -235,7 +235,7 @@
   expected << Tag{"b"} << "foo" << CTag{"b"} << "barbaz";
   LogBuffer actual;
   actual << HighlightValue("foobarbaz", "foo");
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, HighlightAtEnd) {
@@ -243,7 +243,7 @@
   expected << "foobar" << Tag{"b"} << "baz" << CTag{"b"};
   LogBuffer actual;
   actual << HighlightValue("foobarbaz", "baz");
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, HighlightEmpty) {
@@ -251,7 +251,7 @@
   expected << "foobarbaz";
   LogBuffer actual;
   actual << HighlightValue("foobarbaz", "");
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, HighlightNotFound) {
@@ -259,7 +259,7 @@
   expected << "foobarbaz";
   LogBuffer actual;
   actual << HighlightValue("foobarbaz", "notfound");
-  EXPECT_EQ(expected.RetrieveResult(), actual.RetrieveResult());
+  EXPECT_EQ(*expected.RetrieveResult(), *actual.RetrieveResult());
 }
 
 TEST(LogBuffer, HighlightEmptyString) {
diff --git a/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/camera_scan/AssistantQrCodeCameraScanDialog.java b/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/camera_scan/AssistantQrCodeCameraScanDialog.java
index 01b8acb..ca430f2 100644
--- a/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/camera_scan/AssistantQrCodeCameraScanDialog.java
+++ b/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/camera_scan/AssistantQrCodeCameraScanDialog.java
@@ -7,11 +7,13 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Bundle;
 
 import androidx.appcompat.app.AlertDialog;
 
 import org.chromium.components.autofill_assistant.guided_browsing.R;
+import org.chromium.components.autofill_assistant.guided_browsing.qr_code.AssistantQrCodeDelegate;
 import org.chromium.ui.base.WindowAndroid;
 
 /**
@@ -70,6 +72,19 @@
         mCameraScanCoordinator.pause();
     }
 
+    /**
+     * Cancel QR Code Scanning via Camera Preview and forward the event via delegate.
+     */
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        super.onCancel(dialog);
+        AssistantQrCodeDelegate delegate =
+                mCameraScanModel.get(AssistantQrCodeCameraScanModel.DELEGATE);
+        if (delegate != null) {
+            delegate.onScanCancelled();
+        }
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
diff --git a/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/image_picker/AssistantQrCodeImagePickerDialog.java b/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/image_picker/AssistantQrCodeImagePickerDialog.java
index 4b9d84cd..a12d8da 100644
--- a/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/image_picker/AssistantQrCodeImagePickerDialog.java
+++ b/components/autofill_assistant/guided_browsing/android/java/src/org/chromium/components/autofill_assistant/guided_browsing/qr_code/image_picker/AssistantQrCodeImagePickerDialog.java
@@ -7,11 +7,13 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Bundle;
 
 import androidx.appcompat.app.AlertDialog;
 
 import org.chromium.components.autofill_assistant.guided_browsing.R;
+import org.chromium.components.autofill_assistant.guided_browsing.qr_code.AssistantQrCodeDelegate;
 import org.chromium.ui.base.WindowAndroid;
 
 /**
@@ -70,6 +72,19 @@
         mImagePickerCoordinator.pause();
     }
 
+    /**
+     * Cancel QR Code Scanning via Image Picker and forward the event via delegate.
+     */
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        super.onCancel(dialog);
+        AssistantQrCodeDelegate delegate =
+                mImagePickerModel.get(AssistantQrCodeImagePickerModel.DELEGATE);
+        if (delegate != null) {
+            delegate.onScanCancelled();
+        }
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
diff --git a/components/browser_ui/media/android/BUILD.gn b/components/browser_ui/media/android/BUILD.gn
index dc2781c..3ea9e3d 100644
--- a/components/browser_ui/media/android/BUILD.gn
+++ b/components/browser_ui/media/android/BUILD.gn
@@ -40,34 +40,59 @@
   sources = [
     "java/res/drawable-hdpi/audio_playing.png",
     "java/res/drawable-hdpi/audio_playing_square.png",
+    "java/res/drawable-hdpi/ic_call_end_white_36dp.png",
     "java/res/drawable-hdpi/ic_fast_forward_white_36dp.png",
     "java/res/drawable-hdpi/ic_fast_rewind_white_36dp.png",
+    "java/res/drawable-hdpi/ic_mic_off_white_36dp.png",
+    "java/res/drawable-hdpi/ic_mic_white_36dp.png",
     "java/res/drawable-hdpi/ic_skip_next_white_36dp.png",
     "java/res/drawable-hdpi/ic_skip_previous_white_36dp.png",
+    "java/res/drawable-hdpi/ic_videocam_off_white_36dp.png",
+    "java/res/drawable-hdpi/ic_videocam_white_36dp.png",
     "java/res/drawable-mdpi/audio_playing.png",
     "java/res/drawable-mdpi/audio_playing_square.png",
+    "java/res/drawable-mdpi/ic_call_end_white_36dp.png",
     "java/res/drawable-mdpi/ic_fast_forward_white_36dp.png",
     "java/res/drawable-mdpi/ic_fast_rewind_white_36dp.png",
+    "java/res/drawable-mdpi/ic_mic_off_white_36dp.png",
+    "java/res/drawable-mdpi/ic_mic_white_36dp.png",
     "java/res/drawable-mdpi/ic_skip_next_white_36dp.png",
     "java/res/drawable-mdpi/ic_skip_previous_white_36dp.png",
+    "java/res/drawable-mdpi/ic_videocam_off_white_36dp.png",
+    "java/res/drawable-mdpi/ic_videocam_white_36dp.png",
     "java/res/drawable-xhdpi/audio_playing.png",
     "java/res/drawable-xhdpi/audio_playing_square.png",
+    "java/res/drawable-xhdpi/ic_call_end_white_36dp.png",
     "java/res/drawable-xhdpi/ic_fast_forward_white_36dp.png",
     "java/res/drawable-xhdpi/ic_fast_rewind_white_36dp.png",
+    "java/res/drawable-xhdpi/ic_mic_off_white_36dp.png",
+    "java/res/drawable-xhdpi/ic_mic_white_36dp.png",
     "java/res/drawable-xhdpi/ic_skip_next_white_36dp.png",
     "java/res/drawable-xhdpi/ic_skip_previous_white_36dp.png",
+    "java/res/drawable-xhdpi/ic_videocam_off_white_36dp.png",
+    "java/res/drawable-xhdpi/ic_videocam_white_36dp.png",
     "java/res/drawable-xxhdpi/audio_playing.png",
     "java/res/drawable-xxhdpi/audio_playing_square.png",
+    "java/res/drawable-xxhdpi/ic_call_end_white_36dp.png",
     "java/res/drawable-xxhdpi/ic_fast_forward_white_36dp.png",
     "java/res/drawable-xxhdpi/ic_fast_rewind_white_36dp.png",
+    "java/res/drawable-xxhdpi/ic_mic_off_white_36dp.png",
+    "java/res/drawable-xxhdpi/ic_mic_white_36dp.png",
     "java/res/drawable-xxhdpi/ic_skip_next_white_36dp.png",
     "java/res/drawable-xxhdpi/ic_skip_previous_white_36dp.png",
+    "java/res/drawable-xxhdpi/ic_videocam_off_white_36dp.png",
+    "java/res/drawable-xxhdpi/ic_videocam_white_36dp.png",
     "java/res/drawable-xxxhdpi/audio_playing.png",
     "java/res/drawable-xxxhdpi/audio_playing_square.png",
+    "java/res/drawable-xxxhdpi/ic_call_end_white_36dp.png",
     "java/res/drawable-xxxhdpi/ic_fast_forward_white_36dp.png",
     "java/res/drawable-xxxhdpi/ic_fast_rewind_white_36dp.png",
+    "java/res/drawable-xxxhdpi/ic_mic_off_white_36dp.png",
+    "java/res/drawable-xxxhdpi/ic_mic_white_36dp.png",
     "java/res/drawable-xxxhdpi/ic_skip_next_white_36dp.png",
     "java/res/drawable-xxxhdpi/ic_skip_previous_white_36dp.png",
+    "java/res/drawable-xxxhdpi/ic_videocam_off_white_36dp.png",
+    "java/res/drawable-xxxhdpi/ic_videocam_white_36dp.png",
   ]
   deps = [
     "//components/browser_ui/strings/android:browser_ui_strings_grd",
diff --git a/components/browser_ui/media/android/java/res/drawable-hdpi/ic_call_end_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_call_end_white_36dp.png
new file mode 100644
index 0000000..90773818
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_call_end_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_off_white_36dp.png
new file mode 100644
index 0000000..c0e773b
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_white_36dp.png
new file mode 100644
index 0000000..2b377a74
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_mic_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_off_white_36dp.png
new file mode 100644
index 0000000..fafc3a3
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_white_36dp.png
new file mode 100644
index 0000000..5c99f19
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-hdpi/ic_videocam_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-mdpi/ic_call_end_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_call_end_white_36dp.png
new file mode 100644
index 0000000..8fb6ffd
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_call_end_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_off_white_36dp.png
new file mode 100644
index 0000000..153d979f
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_white_36dp.png
new file mode 100644
index 0000000..d3d9dc2b
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_mic_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_off_white_36dp.png
new file mode 100644
index 0000000..b09d4dd33
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_white_36dp.png
new file mode 100644
index 0000000..f4e905c55
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-mdpi/ic_videocam_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_call_end_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_call_end_white_36dp.png
new file mode 100644
index 0000000..ff84f1f
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_call_end_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_off_white_36dp.png
new file mode 100644
index 0000000..89ec023
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_white_36dp.png
new file mode 100644
index 0000000..d79f5bb
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_mic_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_off_white_36dp.png
new file mode 100644
index 0000000..b305b70
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_white_36dp.png
new file mode 100644
index 0000000..646115b
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xhdpi/ic_videocam_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_call_end_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_call_end_white_36dp.png
new file mode 100644
index 0000000..3213989
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_call_end_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_off_white_36dp.png
new file mode 100644
index 0000000..03cb6a6
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_white_36dp.png
new file mode 100644
index 0000000..fc3b9246
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_mic_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_off_white_36dp.png
new file mode 100644
index 0000000..54378c0
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_white_36dp.png
new file mode 100644
index 0000000..60f37bc
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxhdpi/ic_videocam_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_call_end_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_call_end_white_36dp.png
new file mode 100644
index 0000000..ad9f949f
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_call_end_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_off_white_36dp.png
new file mode 100644
index 0000000..533c60e
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_white_36dp.png
new file mode 100644
index 0000000..5ec10394
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_mic_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_off_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_off_white_36dp.png
new file mode 100644
index 0000000..59bc5fe065
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_off_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_white_36dp.png b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_white_36dp.png
new file mode 100644
index 0000000..3372697
--- /dev/null
+++ b/components/browser_ui/media/android/java/res/drawable-xxxhdpi/ic_videocam_white_36dp.png
Binary files differ
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
index 8936c88..69eacf0 100644
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -712,6 +712,21 @@
       <message name="IDS_ACCESSIBILITY_SEEK_BACKWARD" desc="The seek backward button that seeks media to an earlier position.">
         Seek backward
       </message>
+      <message name="IDS_ACCESSIBILITY_HANG_UP" desc="The hang up button that hangs up the video call.">
+        Hang up
+      </message>
+      <message name="IDS_ACCESSIBILITY_MUTE_MICROPHONE" desc="The mute microphone button that mutes the microphone of the video call.">
+        Mute microphone
+      </message>
+      <message name="IDS_ACCESSIBILITY_UNMUTE_MICROPHONE" desc="The unmute microphone button that unmutes the microphone of the video call.">
+        Unmute microphone
+      </message>
+      <message name="IDS_ACCESSIBILITY_TURN_ON_CAMERA" desc="The turn on camera button that turns on the camera of the video call.">
+        Turn on camera
+      </message>
+      <message name="IDS_ACCESSIBILITY_TURN_OFF_CAMERA" desc="The turn off camera button that turns off the camera of the video call.">
+        Turn off camera
+      </message>
       <message name="IDS_MEDIA_NOTIFICATION_INCOGNITO" desc="Text used as a placeholder for a media notification about playing media, when notification is shown from Incognito tab.">
         A site is playing media
       </message>
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_HANG_UP.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_HANG_UP.png.sha1
new file mode 100644
index 0000000..7550f63
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_HANG_UP.png.sha1
@@ -0,0 +1 @@
+bc00ecb19f1574c5b10d6384f8a199cc363a0ce0
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_MUTE_MICROPHONE.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_MUTE_MICROPHONE.png.sha1
new file mode 100644
index 0000000..7550f63
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_MUTE_MICROPHONE.png.sha1
@@ -0,0 +1 @@
+bc00ecb19f1574c5b10d6384f8a199cc363a0ce0
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_OFF_CAMERA.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_OFF_CAMERA.png.sha1
new file mode 100644
index 0000000..7550f63
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_OFF_CAMERA.png.sha1
@@ -0,0 +1 @@
+bc00ecb19f1574c5b10d6384f8a199cc363a0ce0
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_ON_CAMERA.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_ON_CAMERA.png.sha1
new file mode 100644
index 0000000..721f26830
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_TURN_ON_CAMERA.png.sha1
@@ -0,0 +1 @@
+830c38bed54a5c2b1783c150806cd5b13320d381
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_UNMUTE_MICROPHONE.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_UNMUTE_MICROPHONE.png.sha1
new file mode 100644
index 0000000..721f26830
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_ACCESSIBILITY_UNMUTE_MICROPHONE.png.sha1
@@ -0,0 +1 @@
+830c38bed54a5c2b1783c150806cd5b13320d381
\ No newline at end of file
diff --git a/components/commerce/core/commerce_feature_list.cc b/components/commerce/core/commerce_feature_list.cc
index 98089593..a613087d 100644
--- a/components/commerce/core/commerce_feature_list.cc
+++ b/components/commerce/core/commerce_feature_list.cc
@@ -70,6 +70,11 @@
 
 }  // namespace
 
+namespace switches {
+// Specifies whether ChromeCart is enabled.
+const char kEnableChromeCart[] = "enable-chrome-cart";
+}  // namespace switches
+
 const base::Feature kCommerceAllowLocalImages{
     "CommerceAllowLocalImages", base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/components/commerce/core/commerce_feature_list.h b/components/commerce/core/commerce_feature_list.h
index d346fb8..a34dfbc 100644
--- a/components/commerce/core/commerce_feature_list.h
+++ b/components/commerce/core/commerce_feature_list.h
@@ -13,6 +13,11 @@
 #include "url/gurl.h"
 
 namespace commerce {
+
+namespace switches {
+extern const char kEnableChromeCart[];
+}
+
 extern const base::Feature kCommercePriceTracking;
 
 // Price tracking variations for Android.
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client.cc b/components/embedder_support/android/metrics/android_metrics_service_client.cc
index 0fef2d04d..cdef5f4 100644
--- a/components/embedder_support/android/metrics/android_metrics_service_client.cc
+++ b/components/embedder_support/android/metrics/android_metrics_service_client.cc
@@ -241,12 +241,8 @@
 
   pref_service_ = pref_service;
 
-  // TODO(crbug/1245347): If and when the Extended Variations Safe Mode
-  // experiment is enabled on Android WebLayer, pass the channel to the
-  // MetricsStateManager.
-  //
-  // Pass an empty file path since the path is for the Extended Variations Safe
-  // Mode experiment and Android embedders are excluded from this experiment.
+  // Pass an empty file path since the path is for Extended Variations Safe
+  // Mode, which is N/A to Android embedders.
   metrics_state_manager_ = MetricsStateManager::Create(
       pref_service_, this, std::wstring(), base::FilePath());
 
diff --git a/components/feedback/BUILD.gn b/components/feedback/BUILD.gn
index 22d1516..be970550 100644
--- a/components/feedback/BUILD.gn
+++ b/components/feedback/BUILD.gn
@@ -6,6 +6,8 @@
 
 static_library("feedback") {
   sources = [
+    "features.cc",
+    "features.h",
     "feedback_common.cc",
     "feedback_common.h",
     "feedback_data.cc",
diff --git a/components/feedback/features.cc b/components/feedback/features.cc
new file mode 100644
index 0000000..6cacecf1
--- /dev/null
+++ b/components/feedback/features.cc
@@ -0,0 +1,22 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/feedback/features.h"
+
+namespace feedback::features {
+
+// Alphabetical:
+
+// Enables feedback tool to save feedback report to local disk.
+// This flag is only for e2e tast test purpose.
+const base::Feature kOsFeedbackSaveReportToLocalForE2ETesting{
+    "OsFeedbackSaveReportToLocalForE2ETesting",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsOsFeedbackSaveReportToLocalForE2ETestingEnabled() {
+  return base::FeatureList::IsEnabled(
+      kOsFeedbackSaveReportToLocalForE2ETesting);
+}
+
+}  // namespace feedback::features
diff --git a/components/feedback/features.h b/components/feedback/features.h
new file mode 100644
index 0000000..c175450
--- /dev/null
+++ b/components/feedback/features.h
@@ -0,0 +1,22 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_FEEDBACK_FEATURES_H_
+#define COMPONENTS_FEEDBACK_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace feedback::features {
+
+// All features in alphabetical order. The features should be documented
+// alongside the definition of their values in the .cc file.
+
+// Alphabetical:
+extern const base::Feature kOsFeedbackSaveReportToLocalForE2ETesting;
+
+extern bool IsOsFeedbackSaveReportToLocalForE2ETestingEnabled();
+
+}  // namespace feedback::features
+
+#endif  // COMPONENTS_FEEDBACK_FEATURES_H_
diff --git a/components/feedback/feedback_report.cc b/components/feedback/feedback_report.cc
index b117983..ceaaa6a 100644
--- a/components/feedback/feedback_report.cc
+++ b/components/feedback/feedback_report.cc
@@ -4,15 +4,19 @@
 
 #include "components/feedback/feedback_report.h"
 
+#include "base/base_paths.h"
 #include "base/bind.h"
+#include "base/feature_list.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer.h"
 #include "base/guid.h"
+#include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/feedback/features.h"
 #include "components/feedback/proto/extension.pb.h"
 
 namespace feedback {
@@ -59,6 +63,23 @@
       FROM_HERE,
       base::BindOnce(&WriteReportOnBlockingPool, reports_path_, file_,
                      base::WrapRefCounted<FeedbackReport>(this)));
+
+  // Write feedback report to tmp directory when flag is on. This is for e2e
+  // tast test verifying feedback report contains certain data. The tast test
+  // will later clean it up after test is done.
+  if (feedback::features::IsOsFeedbackSaveReportToLocalForE2ETestingEnabled()) {
+    base::FilePath tmp_root;
+    base::PathService::Get(base::DIR_TEMP, &tmp_root);
+    const base::FilePath reports_path_for_tast =
+        tmp_root.AppendASCII("feedback-report/");
+    const base::FilePath file_for_tast =
+        reports_path_for_tast.AppendASCII("feedback-report");
+
+    reports_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&WriteReportOnBlockingPool,
+                                  reports_path_for_tast, file_for_tast,
+                                  base::WrapRefCounted<FeedbackReport>(this)));
+  }
 }
 
 FeedbackReport::FeedbackReport(
diff --git a/components/history/core/browser/history_service_observer.h b/components/history/core/browser/history_service_observer.h
index dae3995..b8838cf4 100644
--- a/components/history/core/browser/history_service_observer.h
+++ b/components/history/core/browser/history_service_observer.h
@@ -41,8 +41,12 @@
                             const URLRow& row,
                             base::Time visit_time) {}
 
-  // Called when a `URLRow` is modified without necessarily having a new visit.
-  // This happens in these scenarios:
+  // Called when a URL has a metadata-only update. In situations where a URL has
+  // a metadata-only update AND new visits, both `OnURLsModified` and
+  // `OnURLVisited` will be called. Therefore observers that only care about new
+  // visits should only override `OnURLVisited`.
+  //
+  // These metadata-only updates happen in these scenarios:
   //  1. When the Page Title is updated shortly after the page loads.
   //  2. When `TypedURLSyncBridge` updates the `URLRow` data. This often happens
   //     in addition to adding new visits, so `OnURLVisited` will be called too.
diff --git a/components/lookalikes/core/lookalike_url_util.cc b/components/lookalikes/core/lookalike_url_util.cc
index 3f4e73f3..9d9cfcb 100644
--- a/components/lookalikes/core/lookalike_url_util.cc
+++ b/components/lookalikes/core/lookalike_url_util.cc
@@ -109,25 +109,78 @@
 const int kDefaultLaunchPercentageOnCanaryDev = 90;
 const int kDefaultLaunchPercentageOnBeta = 50;
 
-// Define brand names and popular keywords for using in Combo Squatting
-// heuristic. These lists are manually curated using Chrome metrics.
+// Define skeletons of brand names and popular keywords for using in Combo
+// Squatting heuristic. These lists are manually curated using Chrome metrics.
 // We will check combinations of brand names and popular keywords.
 // e. g. google-login.com or youtubesecure.com.
-const char* kBrandNamesforCSQ[] = {
-    "adobe",     "airbnb",    "alibaba",     "aliexpress",    "amazon",
-    "baidu",     "bestbuy",   "blogspot",    "costco",        "craigslist",
-    "dropbox",   "expedia",   "facebook",    "fedex",         "flickr",
-    "github",    "glassdoor", "gofundme",    "google",        "homedepot",
-    "icloud",    "indeed",    "instagram",   "intuit",        "microsoft",
-    "nbcnews",   "netflix",   "norton",      "nytimes",       "office365",
-    "paypal",    "pinterest", "playstation", "quora",         "reddit",
-    "reuters",   "samsung",   "spotify",     "stackexchange", "stackoverflow",
-    "trello",    "twitch",    "twitter",     "udemy",         "wikipedia",
-    "wordpress", "xfinity",   "yahoo",       "youtube",       "zillow"};
+// In each element of kBrandNamesforCSQ, first string is an original brand name
+// and second string is its skeleton.
+// If you are adding a brand name here, you can generate its skeleton using the
+// format_url binary (components/url_formatter/tools/format_url.cc)
+// TODO(crbug.com/1349490): Generate skeletons of hard coded brand names in
+// Chrome initialization and remove manual adding of skeletons to this list.
+constexpr std::pair<const char*, const char*> kBrandNamesforCSQ[] = {
+    {"adobe", "adobe"},
+    {"airbnb", "airbnb"},
+    {"alibaba", "alibaba"},
+    {"aliexpress", "aliexpress"},
+    {"amazon", "arnazon"},
+    {"baidu", "baidu"},
+    {"bestbuy", "bestbuy"},
+    {"blogspot", "blogspot"},
+    {"costco", "costco"},
+    {"craigslist", "craigslist"},
+    {"dropbox", "dropbox"},
+    {"expedia", "expedia"},
+    {"facebook", "facebook"},
+    {"fedex", "fedex"},
+    {"flickr", "flickr"},
+    {"github", "github"},
+    {"glassdoor", "glassdoor"},
+    {"gofundme", "gofundrne"},
+    {"google", "google"},
+    {"homedepot", "hornedepot"},
+    {"icloud", "icloud"},
+    {"indeed", "indeed"},
+    {"instagram", "instagrarn"},
+    {"intuit", "intuit"},
+    {"microsoft", "rnicrosoft"},
+    {"nbcnews", "nbcnews"},
+    {"netflix", "netflix"},
+    {"norton", "norton"},
+    {"nytimes", "nytirnes"},
+    {"office365", "office365"},
+    {"paypal", "paypal"},
+    {"pinterest", "pinterest"},
+    {"playstation", "playstation"},
+    {"quora", "quora"},
+    {"reddit", "reddit"},
+    {"reuters", "reuters"},
+    {"samsung", "sarnsung"},
+    {"spotify", "spotify"},
+    {"stackexchange", "stackexchange"},
+    {"stackoverflow", "stackoverflow"},
+    {"trello", "trello"},
+    {"twitch", "twitch"},
+    {"twitter", "twitter"},
+    {"uderny", "udemy"},
+    {"wikipedia", "wikipedia"},
+    {"wordpress", "wordpress"},
+    {"xfinity", "xfinity"},
+    {"yahoo", "yahoo"},
+    {"youtube", "youtube"},
+    {"zillow", "zillow"}};
 
-const char* kPopularKeywordsforCSQ[] = {
+// Each element in kSkeletonsOfPopularKeywordsForCSQ is a skeleton of a popular
+// keyword. In contrast to kBrandNamesforCSQ, the original keywords are not
+// included. Because in kBrandNamesforCSQ, original brand names are used to
+// generate the matched domain, and original keywords are not needed for that
+// process.
+// If you are adding a keyword here, you can generate its skeleton
+// using the format_url binary (components/url_formatter/tools/format_url.cc)
+const char* kSkeletonsOfPopularKeywordsForCSQ[] = {
     // Security
-    "account", "activate", "active", "admin",    "login",  "logout",
+    "account", "activate", "active", "adrnin",   "login",  "logout",
     "online",  "password", "secure", "security", "signin", "signout"};
 
 // Minimum length of brand to be checked for Combo Squatting.
@@ -135,8 +188,9 @@
 
 ComboSquattingParams* GetComboSquattingParams() {
   static ComboSquattingParams params{
-      kBrandNamesforCSQ, std::size(kBrandNamesforCSQ), kPopularKeywordsforCSQ,
-      std::size(kPopularKeywordsforCSQ)};
+      kBrandNamesforCSQ, std::size(kBrandNamesforCSQ),
+      kSkeletonsOfPopularKeywordsForCSQ,
+      std::size(kSkeletonsOfPopularKeywordsForCSQ)};
   return &params;
 }
 
@@ -551,15 +605,19 @@
 
 // Extract brand names from engaged sites to be checked for Combo Squatting, if
 // the brand is not one of the hard coded brand names.
-std::vector<std::string> GetBrandNamesFromEngagedSites(
+std::vector<std::pair<std::string, std::string>> GetBrandNamesFromEngagedSites(
     const std::vector<DomainInfo>& engaged_sites) {
-  std::vector<std::string> output;
+  std::vector<std::pair<std::string, std::string>> output;
 
   for (const DomainInfo& engaged_site : engaged_sites) {
-    std::string domain_without_registry = engaged_site.domain_without_registry;
-    if (IsComboSquattingCandidate(domain_without_registry)) {
-      output.emplace_back(domain_without_registry);
-    }
+    url_formatter::Skeletons domain_without_registry_skeletons =
+        engaged_site.domain_without_registry_skeletons;
+    for (const std::string& skeleton : domain_without_registry_skeletons)
+      if (IsComboSquattingCandidate(engaged_site.domain_without_registry)) {
+        std::pair<std::string, std::string> brand_name = {
+            engaged_site.domain_without_registry, skeleton};
+        output.emplace_back(brand_name);
+      }
   }
   return output;
 }
@@ -567,29 +625,31 @@
 // Returns true if the navigated_domain is flagged as Combo Squatting.
 // matched_domain is the suggested domain that will be shown to the user
 // instead of the navigated_domain in the warning UI.
-bool IsComboSquatting(const std::vector<std::string>& brand_names,
-                      const ComboSquattingParams& combo_squatting_params,
-                      const DomainInfo& navigated_domain,
-                      std::string* matched_domain) {
+bool IsComboSquatting(
+    const std::vector<std::pair<std::string, std::string>>& brand_names,
+    const ComboSquattingParams& combo_squatting_params,
+    const DomainInfo& navigated_domain,
+    std::string* matched_domain) {
   // Check if the domain has any brand name and any popular keyword.
   for (auto& brand : brand_names) {
-    DCHECK(IsComboSquattingCandidate(brand));
+    auto brand_name = brand.first;
+    auto brand_skeleton = brand.second;
+    DCHECK(IsComboSquattingCandidate(brand_name));
+    for (auto& skeleton : navigated_domain.domain_without_registry_skeletons) {
+      if (skeleton.size() == brand_skeleton.size() ||
+          skeleton.find(brand_skeleton) == std::string::npos) {
+        continue;
+      }
 
-    if (navigated_domain.domain_without_registry.size() == brand.size() ||
-        navigated_domain.domain_without_registry.find(brand) ==
-            std::string::npos) {
-      continue;
-    }
-
-    for (size_t j = 0; j < combo_squatting_params.num_popular_keywords; j++) {
-      auto* const keyword = combo_squatting_params.popular_keywords[j];
-      if (navigated_domain.domain_without_registry.find(keyword) !=
-              std::string::npos &&
-          std::string(brand).find(keyword) == std::string::npos &&
-          std::string(keyword).find(brand) == std::string::npos) {
-        // TODO(crbug.com/1341320): Compute a better matched_domain.
-        *matched_domain = std::string(brand) + ".com";
-        return true;
+      for (size_t j = 0; j < combo_squatting_params.num_popular_keywords; j++) {
+        auto* const keyword = combo_squatting_params.popular_keywords[j];
+        if (skeleton.find(keyword) != std::string::npos &&
+            std::string(brand_skeleton).find(keyword) == std::string::npos &&
+            std::string(keyword).find(brand_skeleton) == std::string::npos) {
+          // TODO(crbug.com/1341320): Compute a better matched_domain.
+          *matched_domain = brand_name + ".com";
+          return true;
+        }
       }
     }
   }
@@ -598,16 +658,20 @@
 
 }  // namespace
 
-DomainInfo::DomainInfo(const std::string& arg_hostname,
-                       const std::string& arg_domain_and_registry,
-                       const std::string& arg_domain_without_registry,
-                       const url_formatter::IDNConversionResult& arg_idn_result,
-                       const url_formatter::Skeletons& arg_skeletons)
+DomainInfo::DomainInfo(
+    const std::string& arg_hostname,
+    const std::string& arg_domain_and_registry,
+    const std::string& arg_domain_without_registry,
+    const url_formatter::IDNConversionResult& arg_idn_result,
+    const url_formatter::Skeletons& arg_skeletons,
+    const url_formatter::Skeletons& arg_domain_without_registry_skeletons)
     : hostname(arg_hostname),
       domain_and_registry(arg_domain_and_registry),
       domain_without_registry(arg_domain_without_registry),
       idn_result(arg_idn_result),
-      skeletons(arg_skeletons) {}
+      skeletons(arg_skeletons),
+      domain_without_registry_skeletons(arg_domain_without_registry_skeletons) {
+}
 
 DomainInfo::~DomainInfo() = default;
 
@@ -619,7 +683,7 @@
       net::IsHostnameNonUnique(hostname)) {
     return DomainInfo(std::string(), std::string(), std::string(),
                       url_formatter::IDNConversionResult(),
-                      url_formatter::Skeletons());
+                      url_formatter::Skeletons(), url_formatter::Skeletons());
   }
   const std::string domain_and_registry = GetETLDPlusOne(hostname);
   const std::string domain_without_registry =
@@ -632,7 +696,7 @@
   if (domain_and_registry.empty()) {
     return DomainInfo(hostname, domain_and_registry, domain_without_registry,
                       url_formatter::IDNConversionResult(),
-                      url_formatter::Skeletons());
+                      url_formatter::Skeletons(), url_formatter::Skeletons());
   }
   // Compute skeletons using eTLD+1, skipping all spoofing checks. Spoofing
   // checks in url_formatter can cause the converted result to be punycode.
@@ -642,8 +706,13 @@
       url_formatter::UnsafeIDNToUnicodeWithDetails(domain_and_registry);
   const url_formatter::Skeletons skeletons =
       url_formatter::GetSkeletons(idn_result.result);
+
+  const url_formatter::IDNConversionResult domain_without_registry_idn_result =
+      url_formatter::UnsafeIDNToUnicodeWithDetails(domain_without_registry);
+  const url_formatter::Skeletons domain_without_registry_skeletons =
+      url_formatter::GetSkeletons(domain_without_registry_idn_result.result);
   return DomainInfo(hostname, domain_and_registry, domain_without_registry,
-                    idn_result, skeletons);
+                    idn_result, skeletons, domain_without_registry_skeletons);
 }
 
 DomainInfo GetDomainInfo(const GURL& url) {
@@ -1284,7 +1353,8 @@
 void ResetComboSquattingParamsForTesting() {
   ComboSquattingParams* params = GetComboSquattingParams();
   *params = {kBrandNamesforCSQ, std::size(kBrandNamesforCSQ),
-             kPopularKeywordsforCSQ, std::size(kPopularKeywordsforCSQ)};
+             kSkeletonsOfPopularKeywordsForCSQ,
+             std::size(kSkeletonsOfPopularKeywordsForCSQ)};
 }
 
 ComboSquattingType GetComboSquattingType(
@@ -1295,7 +1365,7 @@
       GetComboSquattingParams();
 
   // First check Combo Squatting with hard coded brand names.
-  std::vector<std::string> brand_names;
+  std::vector<std::pair<std::string, std::string>> brand_names;
   for (size_t i = 0; i < combo_squatting_params->num_brand_names; i++) {
     brand_names.emplace_back(combo_squatting_params->brand_names[i]);
   }
diff --git a/components/lookalikes/core/lookalike_url_util.h b/components/lookalikes/core/lookalike_url_util.h
index e4be994..bd3dcc91 100644
--- a/components/lookalikes/core/lookalike_url_util.h
+++ b/components/lookalikes/core/lookalike_url_util.h
@@ -134,10 +134,11 @@
 };
 
 struct ComboSquattingParams {
-  // List of brand names such as "google", "youtube".
-  // Should be usable in domain names (i.e. lower case, no punctuation except
-  // for - etc.)
-  const char* const* brand_names;
+  // An array of brand names (such as "google", "youtube") and their skeletons
+  // (in pairs). The first item in each pair is the brand name and the second
+  // item is its skeleton. Brand names should be usable in domain names (i.e.
+  // lower case, no punctuation except for - etc.)
+  const std::pair<const char*, const char*>* brand_names;
   // Number of brand names in combo_squatting_brand_names.
   size_t num_brand_names;
 
@@ -164,12 +165,16 @@
   const url_formatter::IDNConversionResult idn_result;
   // Skeletons of domain_and_registry field.
   const url_formatter::Skeletons skeletons;
+  // Skeletons of domain_without_registry field.
+  const url_formatter::Skeletons domain_without_registry_skeletons;
 
-  DomainInfo(const std::string& arg_hostname,
-             const std::string& arg_domain_and_registry,
-             const std::string& arg_domain_without_registry,
-             const url_formatter::IDNConversionResult& arg_idn_result,
-             const url_formatter::Skeletons& arg_skeletons);
+  DomainInfo(
+      const std::string& arg_hostname,
+      const std::string& arg_domain_and_registry,
+      const std::string& arg_domain_without_registry,
+      const url_formatter::IDNConversionResult& arg_idn_result,
+      const url_formatter::Skeletons& arg_skeletons,
+      const url_formatter::Skeletons& arg_domain_without_registry_skeletons);
   ~DomainInfo();
   DomainInfo(const DomainInfo& other);
 };
diff --git a/components/lookalikes/core/lookalike_url_util_unittest.cc b/components/lookalikes/core/lookalike_url_util_unittest.cc
index 104c23762..09eefe7 100644
--- a/components/lookalikes/core/lookalike_url_util_unittest.cc
+++ b/components/lookalikes/core/lookalike_url_util_unittest.cc
@@ -17,10 +17,14 @@
 namespace {
 // Tests lists for Combo Squatting. Some of these entries are intended to test
 // for various edge cases and aren't realistic for production.
-const char* const kBrandNames[] = {"google", "youtube", "sample", "example",
-                                   "vices"};
+constexpr std::pair<const char*, const char*> kBrandNames[] = {
+    {"google", "google"},
+    {"youtube", "youtube"},
+    {"sample", "sarnple"},
+    {"example", "exarnple"},
+    {"vices", "vices"}};
 const char* const kPopularKeywords[] = {"online", "login",    "account",
-                                        "ample",  "services", "test"};
+                                        "arnple", "services", "test"};
 const ComboSquattingParams kComboSquattingParams{
     kBrandNames, std::size(kBrandNames), kPopularKeywords,
     std::size(kPopularKeywords)};
@@ -682,6 +686,40 @@
 
       // Not CSQ, brand name (len) is from engaged sites list but it is short.
       {"len-online.com", "", ComboSquattingType::kNone},
+
+      // CSQ, brand name (googlé) is one of the hard coded brand names and has
+      // IDN spoofing as well.
+      {"googlé-login.com", "google.com", ComboSquattingType::kHardCoded},
+
+      // CSQ, brand name (engagedsité) is one of the brand names from engaged
+      // sites and has IDN spoofing as well.
+      {"engagedsité-online.com", "engagedsite.com",
+       ComboSquattingType::kSiteEngagement},
+
+      // CSQ, keyword (lógin) has IDN spoofing.
+      {"google-lógin.com", "google.com", ComboSquattingType::kHardCoded},
+
+      // CSQ, CSQ with more than one brand (googlé, youtubé) with "-" and IDN
+      // spoofing.
+      {"googlé-youtubé-account.com", "google.com",
+       ComboSquattingType::kHardCoded},
+
+      // Not CSQ.
+      {"ónline.googlé", "", ComboSquattingType::kNone},
+
+      // Not CSQ, it has IDN spoofing but brand name (vicé) is part of keyword
+      // (servicé).
+      {"keyservicés.com", "", ComboSquattingType::kNone},
+
+      // CSQ without separator and with IDN spoofing in the keyword.
+      {"lóginsample.com", "sample.com", ComboSquattingType::kHardCoded},
+
+      // CSQ without separator and with IDN spoofing in the brand name.
+      {"loginsamplé.com", "sample.com", ComboSquattingType::kHardCoded},
+
+      // Not CSQ, skeleton of brand name (lén) is from engaged sites list but it
+      // is short.
+      {"lén-online.com", "", ComboSquattingType::kNone},
   };
   for (const TestCase& test_case : kTestCases) {
     auto navigated =
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 334f527b..b74b76b2 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -493,10 +493,6 @@
     "//components/sync/driver:test_support",
     "//components/variations",
     "//components/variations:test_support",
-
-    # TODO(crbug.com/1241702): Clean up version_info when the Variations Safe
-    # Mode experiment is over.
-    "//components/version_info",
     "//extensions/buildflags",
     "//mojo/public/cpp/bindings",
     "//net:test_support",
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc
index 6fe71c3..2916139b 100644
--- a/components/metrics/clean_exit_beacon.cc
+++ b/components/metrics/clean_exit_beacon.cc
@@ -211,14 +211,12 @@
 
 CleanExitBeacon::CleanExitBeacon(const std::wstring& backup_registry_key,
                                  const base::FilePath& user_data_dir,
-                                 PrefService* local_state,
-                                 version_info::Channel channel)
+                                 PrefService* local_state)
     : backup_registry_key_(backup_registry_key),
       user_data_dir_(user_data_dir),
       local_state_(local_state),
       initial_browser_last_live_timestamp_(
-          local_state->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp)),
-      channel_(channel) {
+          local_state->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp)) {
   DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING,
             local_state_->GetInitializationStatus());
 }
diff --git a/components/metrics/clean_exit_beacon.h b/components/metrics/clean_exit_beacon.h
index 417d378..b5c459ba1 100644
--- a/components/metrics/clean_exit_beacon.h
+++ b/components/metrics/clean_exit_beacon.h
@@ -12,7 +12,6 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "components/version_info/channel.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefRegistrySimple;
@@ -71,14 +70,9 @@
   //
   // |user_data_dir| is the path to the client's user data directory. If empty,
   // the beacon file is not used.
-  //
-  // TODO(crbug/1241702): Remove |channel| at the end of the Extended Variations
-  // Safe Mode experiment. |channel| is used to enable the experiment on only
-  // certain channels.
   CleanExitBeacon(const std::wstring& backup_registry_key,
                   const base::FilePath& user_data_dir,
-                  PrefService* local_state,
-                  version_info::Channel channel);
+                  PrefService* local_state);
 
   virtual ~CleanExitBeacon() = default;
 
@@ -216,11 +210,6 @@
   // the browser was known to be alive.
   const base::Time initial_browser_last_live_timestamp_;
 
-  // The client's channel, e.g. Canary. Used to help determine whether the
-  // client should participate in the Extended Variations Safe Mode experiment.
-  // TODO(crbug/1241702): Remove at the end of the experiment.
-  [[maybe_unused]] const version_info::Channel channel_;
-
   bool did_previous_session_exit_cleanly_ = false;
 
   // Denotes the current beacon value for this session, which is updated via
diff --git a/components/metrics/clean_exit_beacon_unittest.cc b/components/metrics/clean_exit_beacon_unittest.cc
index 52e33fc..7fe2554 100644
--- a/components/metrics/clean_exit_beacon_unittest.cc
+++ b/components/metrics/clean_exit_beacon_unittest.cc
@@ -39,12 +39,8 @@
  public:
   explicit TestCleanExitBeacon(
       PrefService* local_state,
-      const base::FilePath& user_data_dir = base::FilePath(),
-      version_info::Channel channel = version_info::Channel::UNKNOWN)
-      : CleanExitBeacon(kDummyWindowsRegistryKey,
-                        user_data_dir,
-                        local_state,
-                        channel) {
+      const base::FilePath& user_data_dir = base::FilePath())
+      : CleanExitBeacon(kDummyWindowsRegistryKey, user_data_dir, local_state) {
     Initialize();
   }
 
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc
index 985e13a..43e1e79 100644
--- a/components/metrics/metrics_state_manager.cc
+++ b/components/metrics/metrics_state_manager.cc
@@ -236,7 +236,6 @@
     const std::wstring& backup_registry_key,
     const base::FilePath& user_data_dir,
     StartupVisibility startup_visibility,
-    version_info::Channel channel,
     StoreClientInfoCallback store_client_info,
     LoadClientInfoCallback retrieve_client_info,
     base::StringPiece external_client_id)
@@ -244,10 +243,7 @@
       enabled_state_provider_(enabled_state_provider),
       store_client_info_(std::move(store_client_info)),
       load_client_info_(std::move(retrieve_client_info)),
-      clean_exit_beacon_(backup_registry_key,
-                         user_data_dir,
-                         local_state,
-                         channel),
+      clean_exit_beacon_(backup_registry_key, user_data_dir, local_state),
       external_client_id_(external_client_id),
       entropy_state_(local_state),
       entropy_source_returned_(ENTROPY_SOURCE_NONE),
@@ -574,7 +570,6 @@
     const std::wstring& backup_registry_key,
     const base::FilePath& user_data_dir,
     StartupVisibility startup_visibility,
-    version_info::Channel channel,
     StoreClientInfoCallback store_client_info,
     LoadClientInfoCallback retrieve_client_info,
     base::StringPiece external_client_id) {
@@ -583,7 +578,7 @@
   if (!instance_exists_) {
     result.reset(new MetricsStateManager(
         local_state, enabled_state_provider, backup_registry_key, user_data_dir,
-        startup_visibility, channel,
+        startup_visibility,
         store_client_info.is_null() ? base::DoNothing()
                                     : std::move(store_client_info),
         retrieve_client_info.is_null()
diff --git a/components/metrics/metrics_state_manager.h b/components/metrics/metrics_state_manager.h
index bb865d7..557e2a8 100644
--- a/components/metrics/metrics_state_manager.h
+++ b/components/metrics/metrics_state_manager.h
@@ -18,7 +18,6 @@
 #include "components/metrics/client_info.h"
 #include "components/metrics/cloned_install_detector.h"
 #include "components/metrics/entropy_state.h"
-#include "components/version_info/channel.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "components/metrics/structured/neutrino_logging.h"  // nogncheck
@@ -196,17 +195,12 @@
   //
   // |startup_visibility| denotes whether this session is expected to come to
   // the foreground.
-  //
-  // TODO(crbug/1241702): Remove |channel| at the end of the Extended Variations
-  // Safe Mode experiment. |channel| is used to enable the experiment on only
-  // certain channels.
   static std::unique_ptr<MetricsStateManager> Create(
       PrefService* local_state,
       EnabledStateProvider* enabled_state_provider,
       const std::wstring& backup_registry_key,
       const base::FilePath& user_data_dir,
       StartupVisibility startup_visibility = StartupVisibility::kUnknown,
-      version_info::Channel channel = version_info::Channel::UNKNOWN,
       StoreClientInfoCallback store_client_info = StoreClientInfoCallback(),
       LoadClientInfoCallback load_client_info = LoadClientInfoCallback(),
       base::StringPiece external_client_id = base::StringPiece());
@@ -277,7 +271,6 @@
                       const std::wstring& backup_registry_key,
                       const base::FilePath& user_data_dir,
                       StartupVisibility startup_visibility,
-                      version_info::Channel channel,
                       StoreClientInfoCallback store_client_info,
                       LoadClientInfoCallback load_client_info,
                       base::StringPiece external_client_id);
diff --git a/components/metrics/metrics_state_manager_unittest.cc b/components/metrics/metrics_state_manager_unittest.cc
index 1c7efc1..4eefdb5f 100644
--- a/components/metrics/metrics_state_manager_unittest.cc
+++ b/components/metrics/metrics_state_manager_unittest.cc
@@ -29,7 +29,6 @@
 #include "components/metrics/test/test_enabled_state_provider.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/variations/pref_names.h"
-#include "components/version_info/channel.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -83,7 +82,6 @@
         MetricsStateManager::Create(
             &prefs_, enabled_state_provider_.get(), std::wstring(),
             base::FilePath(), StartupVisibility::kUnknown,
-            version_info::Channel::UNKNOWN,
             base::BindRepeating(
                 &MetricsStateManagerTest::MockStoreClientInfoBackup,
                 base::Unretained(this)),
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 5d08ee9..2a3a4288 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -92,6 +92,31 @@
          input_text.size() >= min_char;
 }
 
+// Gives a basis for match comparison that prefers some providers over others
+// while remaining neutral with a default score of zero for most providers.
+int GetDeduplicationProviderPreferenceScore(AutocompleteProvider::Type type) {
+  const static std::unordered_map<AutocompleteProvider::Type, int>
+      provider_preference = {
+          {// Prefer live document suggestions. We check provider type instead
+           // of match type in order to distinguish live suggestions from the
+           // document provider from stale suggestions from the shortcuts
+           // providers, because the latter omits changing metadata such as last
+           // access date.
+           AutocompleteProvider::TYPE_DOCUMENT, 2},
+          {// Prefer bookmark suggestions, as 1) their titles may be explicitly
+           // set, and 2) they may display enhanced information such as the
+           // bookmark folders path.
+           AutocompleteProvider::TYPE_BOOKMARK, 1},
+          {// Prefer non-fuzzy matches over fuzzy matches.
+           AutocompleteProvider::TYPE_HISTORY_FUZZY, -1},
+      };
+  const auto it = provider_preference.find(type);
+  if (it == provider_preference.end()) {
+    return 0;
+  }
+  return it->second;
+}
+
 }  // namespace
 
 RichAutocompletionParams::RichAutocompletionParams()
@@ -542,26 +567,13 @@
       return false;
   }
 
-  // Prefer some providers over others.
-  const std::vector<AutocompleteProvider::Type> preferred_providers = {
-      // Prefer live document suggestions. We check provider type instead of
-      // match type in order to distinguish live suggestions from the document
-      // provider from stale suggestions from the shortcuts providers, because
-      // the latter omits changing metadata such as last access date.
-      AutocompleteProvider::TYPE_DOCUMENT,
-      // Prefer bookmark suggestions, as 1) their titles may be explicitly set,
-      // and 2) they may display enhanced information such as the bookmark
-      // folders path.
-      AutocompleteProvider::TYPE_BOOKMARK,
-  };
-
-  if (match1.provider->type() != match2.provider->type()) {
-    for (const auto& preferred_provider : preferred_providers) {
-      if (match1.provider->type() == preferred_provider)
-        return true;
-      if (match2.provider->type() == preferred_provider)
-        return false;
-    }
+  // Prefer some providers above others according to score (default is zero).
+  const int match1_score =
+      GetDeduplicationProviderPreferenceScore(match1.provider->type());
+  const int match2_score =
+      GetDeduplicationProviderPreferenceScore(match2.provider->type());
+  if (match1_score != match2_score) {
+    return match1_score > match2_score;
   }
 
   // By default, simply prefer the more relevant match.
diff --git a/components/omnibox/browser/history_fuzzy_provider.cc b/components/omnibox/browser/history_fuzzy_provider.cc
index 19614c22..ae007557 100644
--- a/components/omnibox/browser/history_fuzzy_provider.cc
+++ b/components/omnibox/browser/history_fuzzy_provider.cc
@@ -562,6 +562,7 @@
     // normal), the matches are cleared here instead of at end of result
     // processing pipeline so they won't interact or dedupe with other matches.
     if (OmniboxFieldTrial::kFuzzyUrlSuggestionsCounterfactual.Get()) {
+      DVLOG(1) << "Clearing matches_ for counterfactual";
       matches_.clear();
     }
   }
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index b114920..ca8c455 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -62,6 +62,7 @@
 #include "third_party/metrics_proto/omnibox_event.pb.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/window_open_disposition.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/image/image.h"
 #include "url/url_util.h"
@@ -803,15 +804,24 @@
                                  const std::u16string& pasted_text,
                                  size_t index,
                                  base::TimeTicks match_selection_timestamp) {
-  // Switch the window disposition to SWITCH_TO_TAB for open tab matches that
-  // originated while in keyword mode.  This is to support the keyword mode
-  // starter pack's tab search (@tabs) feature, which should open all
-  // suggestions in the existing open tab.
-  bool is_open_tab_match =
+  TemplateURLService* service = client_->GetTemplateURLService();
+  bool is_tab_search_mode =
       OmniboxFieldTrial::IsSiteSearchStarterPackEnabled() &&
       match.from_keyword &&
-      match.provider->type() == AutocompleteProvider::TYPE_OPEN_TAB;
-  if (is_open_tab_match) {
+      service->IsKeywordFromStarterPackTabSearch(keyword_);
+  if (is_tab_search_mode) {
+    // The starter pack's tab search feature uses the omnibox's OpenTabProvider
+    // to search through a user's open tabs and does not have a proper landing
+    // page for substituting URL searches. To support this, only allow the user
+    // to open matches from the OpenTabProvider, effectively disabling the 
+    // search-other-engine suggestion that is usually the default suggestion in
+    // keyword mode.
+    if (match.provider->type() != AutocompleteProvider::TYPE_OPEN_TAB) {
+      return;
+    }
+
+    // All suggestions in tab search mode that ARE from the open tab provider
+    // should open in the existing open tab (switch to open tab).
     disposition = WindowOpenDisposition::SWITCH_TO_TAB;
   }
 
@@ -920,7 +930,6 @@
                                now - last_omnibox_focus_);
   }
 
-  TemplateURLService* service = client_->GetTemplateURLService();
   TemplateURL* template_url = match.GetTemplateURL(service, false);
   if (template_url) {
     if (ui::PageTransitionTypeIncludingQualifiersIs(
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc
index 320f6524..c766452 100644
--- a/components/omnibox/browser/omnibox_edit_model_unittest.cc
+++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -31,6 +31,7 @@
 #include "components/omnibox/browser/test_scheme_classifier.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/prefs/testing_pref_service.h"
+#include "components/search_engines/template_url_starter_pack_data.h"
 #include "components/url_formatter/url_fixer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/metrics_proto/omnibox_event.pb.h"
@@ -1204,16 +1205,27 @@
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(omnibox::kSiteSearchStarterPack);
 
-  // When the match comes from the Open Tab Provider while in keyword mode,
-  // the disposition should be set to SWITCH_TO_TAB.
+  // Populate template URL with starter pack entries
+  std::vector<std::unique_ptr<TemplateURLData>> turls =
+      TemplateURLStarterPackData::GetStarterPackEngines();
+  for (auto& turl : turls) {
+    model()->client()->GetTemplateURLService()->Add(
+        std::make_unique<TemplateURL>(std::move(*turl)));
+  }
+
+  // When the match comes from the Open Tab Provider while in tabs search
+  // keyword mode, the disposition should be set to SWITCH_TO_TAB.
   AutocompleteMatch match(
       model()->autocomplete_controller()->open_tab_provider(), 0, false,
       AutocompleteMatchType::OPEN_TAB);
   match.destination_url = GURL("https://foo/");
   match.from_keyword = true;
 
-  model()->OnSetFocus(false);  // Avoids DCHECK in OpenMatch().
-  model()->SetUserText(u"http://abcd");
+  // Set the keyword to "@tabs" to put us in tab search mode.
+  model()->OnPopupDataChanged(std::u16string(), false, std::u16string(),
+                              std::u16string(), /* keyword = */ u"@tabs", false,
+                              std::u16string());
+
   model()->OpenMatch(match, WindowOpenDisposition::CURRENT_TAB, GURL(),
                      std::u16string(), 0);
   EXPECT_EQ(controller_->disposition(), WindowOpenDisposition::SWITCH_TO_TAB);
@@ -1230,5 +1242,15 @@
   model()->OpenMatch(match, WindowOpenDisposition::CURRENT_TAB, GURL(),
                      std::u16string(), 0);
   EXPECT_EQ(controller_->disposition(), WindowOpenDisposition::CURRENT_TAB);
+
+  // Suggestions in keyword mode but NOT in tab search should NOT change the
+  // disposition.
+  model()->OnPopupDataChanged(std::u16string(), false, std::u16string(),
+                              std::u16string(), /* keyword = */ u"@history",
+                              false, std::u16string());
+  match.provider = model()->autocomplete_controller()->open_tab_provider();
+  model()->OpenMatch(match, WindowOpenDisposition::CURRENT_TAB, GURL(),
+                     std::u16string(), 0);
+  EXPECT_EQ(controller_->disposition(), WindowOpenDisposition::CURRENT_TAB);
 }
 #endif  // !(BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID))
diff --git a/components/optimization_guide/core/hint_cache.cc b/components/optimization_guide/core/hint_cache.cc
index 8ef8c2d..37e2032 100644
--- a/components/optimization_guide/core/hint_cache.cc
+++ b/components/optimization_guide/core/hint_cache.cc
@@ -375,6 +375,10 @@
         // Old component versions if not updated could potentially have
         // HOST_SUFFIX hints. Just skip over them.
         break;
+      case proto::HASHED_HOST:
+        // The server should not send hints with hashed host key.
+        NOTREACHED();
+        break;
       case proto::REPRESENTATION_UNSPECIFIED:
         NOTREACHED();
         break;
diff --git a/components/optimization_guide/proto/hints.proto b/components/optimization_guide/proto/hints.proto
index 5a0ece2d..d1535ff 100644
--- a/components/optimization_guide/proto/hints.proto
+++ b/components/optimization_guide/proto/hints.proto
@@ -37,6 +37,14 @@
   optional string url = 1;
 }
 
+// Information about the set of host hashes to retrieve hints for.
+message HashedHostInfos {
+  // The partial host hash will be the first num_hash_bits least significant bit
+  // of the hashed host.
+  repeated uint32 partial_host_hashes = 1;
+  optional uint32 num_hash_bits = 2;
+}
+
 // Request to return a set of hints that guide what optimizations to perform
 // on those hosts.
 message GetHintsRequest {
@@ -48,6 +56,9 @@
   // Information about the set of URLs to retrieve hints for.
   repeated UrlInfo urls = 4;
 
+  // Information about the set of host hashes to retrieve hints for.
+  optional HashedHostInfos hashed_hosts = 8;
+
   // The set of optimization types that the requesting client can support
   // and perform.
   //
@@ -185,6 +196,8 @@
   //
   // This will be an exact match of a page load host.
   HOST = 3;
+  // This will be a partial hash of a page load host.
+  HASHED_HOST = 4;
 }
 
 message Optimization {
diff --git a/components/password_manager/content/browser/password_manager_log_router_factory_unittest.cc b/components/password_manager/content/browser/password_manager_log_router_factory_unittest.cc
index 54b30627..cea58a3 100644
--- a/components/password_manager/content/browser/password_manager_log_router_factory_unittest.cc
+++ b/components/password_manager/content/browser/password_manager_log_router_factory_unittest.cc
@@ -21,7 +21,7 @@
 
 class MockLogReceiver : public autofill::LogReceiver {
  public:
-  MOCK_METHOD1(LogEntry, void(const base::Value&));
+  MOCK_METHOD1(LogEntry, void(const base::Value::Dict&));
 };
 
 }  // namespace
@@ -53,7 +53,8 @@
   ASSERT_TRUE(log_router);
   log_router->RegisterReceiver(&receiver);
 
-  base::Value log_entry = autofill::LogRouter::CreateEntryForText(kTestText);
+  base::Value::Dict log_entry =
+      autofill::LogRouter::CreateEntryForText(kTestText);
   EXPECT_CALL(receiver, LogEntry(testing::Eq(testing::ByRef(log_entry))))
       .Times(1);
   log_router->ProcessLog(kTestText);
diff --git a/components/reporting/client/report_queue_configuration.h b/components/reporting/client/report_queue_configuration.h
index d00bb0f4..9fe9292 100644
--- a/components/reporting/client/report_queue_configuration.h
+++ b/components/reporting/client/report_queue_configuration.h
@@ -66,7 +66,7 @@
       Destination destination,
       PolicyCheckCallback policy_check_callback);
 
-  reporting::Destination destination() const { return destination_; }
+  Destination destination() const { return destination_; }
 
   std::string dm_token() { return dm_token_; }
 
@@ -80,12 +80,12 @@
   ReportQueueConfiguration();
 
   Status SetEventType(EventType event_type);
-  Status SetDestination(reporting::Destination destination);
+  Status SetDestination(Destination destination);
   Status SetPolicyCheckCallback(PolicyCheckCallback policy_check_callback);
 
   std::string dm_token_;
   EventType event_type_;
-  reporting::Destination destination_;
+  Destination destination_;
 
   PolicyCheckCallback policy_check_callback_;
 };
diff --git a/components/reporting/client/report_queue_factory.h b/components/reporting/client/report_queue_factory.h
index 0efef47e..6643318 100644
--- a/components/reporting/client/report_queue_factory.h
+++ b/components/reporting/client/report_queue_factory.h
@@ -51,7 +51,7 @@
  private:
   static void TrySetReportQueue(
       SuccessCallback success_cb,
-      StatusOr<std::unique_ptr<reporting::ReportQueue>> report_queue_result);
+      StatusOr<std::unique_ptr<ReportQueue>> report_queue_result);
 
   static TrySetReportQueueCallback CreateTrySetCallback(
       Destination destination,
diff --git a/components/reporting/client/report_queue_factory_unittest.cc b/components/reporting/client/report_queue_factory_unittest.cc
index 86f0204..ec3f7c6c 100644
--- a/components/reporting/client/report_queue_factory_unittest.cc
+++ b/components/reporting/client/report_queue_factory_unittest.cc
@@ -38,8 +38,8 @@
       waiter->Signal();
     }
   }
-  base::OnceCallback<void(std::unique_ptr<reporting::ReportQueue>)>
-  GetReportQueueSetter(test::TestCallbackWaiter* waiter) {
+  base::OnceCallback<void(std::unique_ptr<ReportQueue>)> GetReportQueueSetter(
+      test::TestCallbackWaiter* waiter) {
     return base::BindOnce(&MockReportQueueConsumer::SetReportQueue,
                           weak_factory_.GetWeakPtr(), base::Unretained(waiter));
   }
@@ -77,9 +77,8 @@
   EXPECT_FALSE(consumer_->GetReportQueue());
   {
     test::TestCallbackAutoWaiter set_waiter;
-    reporting::ReportQueueFactory::Create(
-        EventType::kDevice, destination_,
-        consumer_->GetReportQueueSetter(&set_waiter));
+    ReportQueueFactory::Create(EventType::kDevice, destination_,
+                               consumer_->GetReportQueueSetter(&set_waiter));
     EXPECT_CALL(*provider_.get(), OnInitCompletedMock()).Times(1);
     provider_->ExpectCreateNewQueueAndReturnNewMockQueue(1);
   }
@@ -90,9 +89,9 @@
 TEST_F(ReportQueueFactoryTest, CreateQueueWithInvalidConfig) {
   // Initially the queue must be an uninitialized unique_ptr
   EXPECT_FALSE(consumer_->GetReportQueue());
-  reporting::ReportQueueFactory::Create(
-      EventType::kDevice, Destination::UNDEFINED_DESTINATION,
-      consumer_->GetReportQueueSetter(nullptr));
+  ReportQueueFactory::Create(EventType::kDevice,
+                             Destination::UNDEFINED_DESTINATION,
+                             consumer_->GetReportQueueSetter(nullptr));
   // Expect failure before it gets to the report queue provider
   EXPECT_CALL(*provider_.get(), OnInitCompletedMock()).Times(0);
   // We do not expect the report queue to be existing in the consumer.
@@ -102,16 +101,14 @@
 TEST_F(ReportQueueFactoryTest, CreateSpeculativeQueue) {
   // Mock internal implementation to use a MockReportQueue
   provider_->ExpectCreateNewSpeculativeQueueAndReturnNewMockQueue(1);
-  const auto report_queue =
-      reporting::ReportQueueFactory::CreateSpeculativeReportQueue(
-          EventType::kDevice, destination_);
+  const auto report_queue = ReportQueueFactory::CreateSpeculativeReportQueue(
+      EventType::kDevice, destination_);
   EXPECT_THAT(report_queue, NotNull());
 }
 
 TEST_F(ReportQueueFactoryTest, CreateSpeculativeQueueWithInvalidConfig) {
-  const auto report_queue =
-      reporting::ReportQueueFactory::CreateSpeculativeReportQueue(
-          EventType::kDevice, Destination::UNDEFINED_DESTINATION);
+  const auto report_queue = ReportQueueFactory::CreateSpeculativeReportQueue(
+      EventType::kDevice, Destination::UNDEFINED_DESTINATION);
   EXPECT_THAT(report_queue, IsNull());
 }
 
@@ -123,12 +120,10 @@
   {
     test::TestCallbackAutoWaiter set_waiter;
     set_waiter.Attach();
-    reporting::ReportQueueFactory::Create(
-        EventType::kDevice, destination_,
-        consumer_->GetReportQueueSetter(&set_waiter));
-    reporting::ReportQueueFactory::Create(
-        EventType::kUser, destination_,
-        consumer2->GetReportQueueSetter(&set_waiter));
+    ReportQueueFactory::Create(EventType::kDevice, destination_,
+                               consumer_->GetReportQueueSetter(&set_waiter));
+    ReportQueueFactory::Create(EventType::kUser, destination_,
+                               consumer2->GetReportQueueSetter(&set_waiter));
     EXPECT_CALL(*provider_.get(), OnInitCompletedMock()).Times(1);
     provider_->ExpectCreateNewQueueAndReturnNewMockQueue(2);
   }
diff --git a/components/reporting/health/health_module_delegate_unittest.cc b/components/reporting/health/health_module_delegate_unittest.cc
index 4ad4d77..7867173 100644
--- a/components/reporting/health/health_module_delegate_unittest.cc
+++ b/components/reporting/health/health_module_delegate_unittest.cc
@@ -61,10 +61,9 @@
   const std::string file_name = base::StrCat({kBaseFileOne, "0"});
   auto call = AddEnqueueRecordCall();
   *ref_data.add_history() = call;
-  ASSERT_TRUE(
-      ::reporting::AppendLine(temp_dir_.GetPath().AppendASCII(file_name),
-                              BytesToHexString(call.SerializeAsString()))
-          .ok());
+  ASSERT_TRUE(AppendLine(temp_dir_.GetPath().AppendASCII(file_name),
+                         BytesToHexString(call.SerializeAsString()))
+                  .ok());
 
   HealthModuleDelegate delegate(temp_dir_.GetPath(), kBaseFileOne, kMaxStorage);
   ASSERT_FALSE(delegate.IsInitialized());
diff --git a/components/reporting/health/health_module_files.cc b/components/reporting/health/health_module_files.cc
index d32d1c5..977829c 100644
--- a/components/reporting/health/health_module_files.cc
+++ b/components/reporting/health/health_module_files.cc
@@ -132,7 +132,7 @@
 
   // +1 for newline char.
   storage_used_ += data.size() + 1;
-  return ::reporting::AppendLine(files_.rbegin()->second, data);
+  return AppendLine(files_.rbegin()->second, data);
 }
 
 Status HealthModuleFiles::FreeStorage(uint32_t storage) {
@@ -151,7 +151,7 @@
       storage_removed += file_size;
     } else {
       ASSIGN_OR_RETURN(uint32_t remove_result,
-                       ::reporting::RemoveAndTruncateLine(
+                       RemoveAndTruncateLine(
                            file_path, storage_to_remove - storage_removed - 1));
       storage_removed += remove_result;
     }
diff --git a/components/reporting/health/health_module_files_unittest.cc b/components/reporting/health/health_module_files_unittest.cc
index 737c773..b8fb2b6 100644
--- a/components/reporting/health/health_module_files_unittest.cc
+++ b/components/reporting/health/health_module_files_unittest.cc
@@ -50,10 +50,9 @@
       for (int k = 0; k < kIntialRecordsPerFile; k++) {
         auto call = AddEnqueueRecordCall();
         *initial_health_data_.add_history() = call;
-        ASSERT_TRUE(
-            ::reporting::AppendLine(directory_.GetPath().AppendASCII(file_name),
-                                    BytesToHexString(call.SerializeAsString()))
-                .ok());
+        ASSERT_TRUE(AppendLine(directory_.GetPath().AppendASCII(file_name),
+                               BytesToHexString(call.SerializeAsString()))
+                        .ok());
       }
     }
   }
diff --git a/components/reporting/util/disconnectable_client.cc b/components/reporting/util/disconnectable_client.cc
index af106a3..e1adf98 100644
--- a/components/reporting/util/disconnectable_client.cc
+++ b/components/reporting/util/disconnectable_client.cc
@@ -31,8 +31,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Bail out, if missive daemon is not available over dBus.
   if (!is_available_) {
-    delegate->Respond(
-        Status(reporting::error::UNAVAILABLE, "Service is unavailable"));
+    delegate->Respond(Status(error::UNAVAILABLE, "Service is unavailable"));
     return;
   }
   // Add the delegate to the map.
@@ -69,8 +68,7 @@
       const auto delegate = std::move(outstanding_delegates_.begin()->second);
       outstanding_delegates_.erase(outstanding_delegates_.begin());
       // Respond through the |delegate|.
-      delegate->Respond(
-          Status(reporting::error::UNAVAILABLE, "Service is unavailable"));
+      delegate->Respond(Status(error::UNAVAILABLE, "Service is unavailable"));
     }
   }
 }
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
index 01e7ef1..6687cf6 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -1445,7 +1445,7 @@
   return base::Value(verdict);
 }
 
-base::Value SerializePGEvent(const sync_pb::UserEventSpecifics& event) {
+base::Value::Dict SerializePGEvent(const sync_pb::UserEventSpecifics& event) {
   base::Value::Dict result;
 
   base::Time timestamp = base::Time::FromDeltaSinceWindowsEpoch(
@@ -1540,10 +1540,11 @@
   serializer.set_pretty_print(true);
   serializer.Serialize(event_dict);
   result.Set("message", event_serialized);
-  return base::Value(std::move(result));
+  return result;
 }
 
-base::Value SerializeSecurityEvent(const sync_pb::GaiaPasswordReuse& event) {
+base::Value::Dict SerializeSecurityEvent(
+    const sync_pb::GaiaPasswordReuse& event) {
   base::Value::Dict result;
 
   base::Value::Dict event_dict;
@@ -1561,7 +1562,7 @@
   serializer.set_pretty_print(true);
   serializer.Serialize(event_dict);
   result.Set("message", event_serialized);
-  return base::Value(std::move(result));
+  return result;
 }
 
 base::Value::Dict SerializeFrame(
@@ -1766,7 +1767,7 @@
   return d;
 }
 
-base::Value SerializeReferringAppInfo(
+base::Value::Dict SerializeReferringAppInfo(
     const LoginReputationClientRequest::ReferringAppInfo& info) {
   base::Value::Dict dict;
 
@@ -1789,7 +1790,7 @@
   dict.Set("referring_app_source", source);
   dict.Set("referring_app_info", info.referring_app_name());
 
-  return base::Value(std::move(dict));
+  return dict;
 }
 
 std::string SerializePGPing(
@@ -1983,15 +1984,15 @@
   return response_serialized;
 }
 
-base::Value SerializeLogMessage(const base::Time& timestamp,
-                                const std::string& message) {
+base::Value::Dict SerializeLogMessage(const base::Time& timestamp,
+                                      const std::string& message) {
   base::Value::Dict result;
   result.Set("time", timestamp.ToJsTime());
   result.Set("message", message);
-  return base::Value(std::move(result));
+  return result;
 }
 
-base::Value SerializeReportingEvent(const base::Value::Dict& event) {
+base::Value::Dict SerializeReportingEvent(const base::Value::Dict& event) {
   base::Value::Dict result;
 
   std::string event_serialized;
@@ -2001,7 +2002,7 @@
 
   result.Set("message", event_serialized);
 
-  return base::Value(std::move(result));
+  return result;
 }
 
 #if BUILDFLAG(FULL_SAFE_BROWSING)
@@ -2162,8 +2163,8 @@
   return response_serialized;
 }
 
-base::Value SerializeDeepScanDebugData(const std::string& token,
-                                       const DeepScanDebugData& data) {
+base::Value::Dict SerializeDeepScanDebugData(const std::string& token,
+                                             const DeepScanDebugData& data) {
   base::Value::Dict value;
   value.Set("token", token);
 
@@ -2190,7 +2191,7 @@
               SerializeContentAnalysisResponse(data.response.value()));
   }
 
-  return base::Value(std::move(value));
+  return value;
 }
 
 #endif
@@ -2300,8 +2301,7 @@
   response.Append(time);
 
   AllowJavascript();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(callback_id), response);
 }
 
 void SafeBrowsingUIHandler::GetSavedPasswords(const base::Value::List& args) {
@@ -2318,8 +2318,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(saved_passwords)));
+  ResolveJavascriptCallback(base::Value(callback_id), saved_passwords);
 }
 
 void SafeBrowsingUIHandler::GetDatabaseManagerInfo(
@@ -2354,8 +2353,7 @@
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
 
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(database_manager_info)));
+  ResolveJavascriptCallback(base::Value(callback_id), database_manager_info);
 }
 
 std::string SerializeDownloadUrlChecked(const std::vector<GURL>& urls,
@@ -2440,8 +2438,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(urls_checked_value)));
+  ResolveJavascriptCallback(base::Value(callback_id), urls_checked_value);
 }
 
 void SafeBrowsingUIHandler::GetSentClientDownloadRequests(
@@ -2458,8 +2455,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(cdrs_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), cdrs_sent);
 }
 
 void SafeBrowsingUIHandler::GetReceivedClientDownloadResponses(
@@ -2476,8 +2472,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(cdrs_received)));
+  ResolveJavascriptCallback(base::Value(callback_id), cdrs_received);
 }
 
 void SafeBrowsingUIHandler::GetSentClientPhishingRequests(
@@ -2494,8 +2489,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(cprs_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), cprs_sent);
 }
 
 void SafeBrowsingUIHandler::GetReceivedClientPhishingResponses(
@@ -2512,8 +2506,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(cprs_received)));
+  ResolveJavascriptCallback(base::Value(callback_id), cprs_received);
 }
 
 void SafeBrowsingUIHandler::GetSentCSBRRs(const base::Value::List& args) {
@@ -2529,8 +2522,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(sent_reports)));
+  ResolveJavascriptCallback(base::Value(callback_id), sent_reports);
 }
 
 void SafeBrowsingUIHandler::GetSentHitReports(const base::Value::List& args) {
@@ -2546,8 +2538,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(sent_reports)));
+  ResolveJavascriptCallback(base::Value(callback_id), sent_reports);
 }
 
 void SafeBrowsingUIHandler::GetPGEvents(const base::Value::List& args) {
@@ -2562,8 +2553,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(events_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), events_sent);
 }
 
 void SafeBrowsingUIHandler::GetSecurityEvents(const base::Value::List& args) {
@@ -2578,8 +2568,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(events_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), events_sent);
 }
 
 void SafeBrowsingUIHandler::GetPGPings(const base::Value::List& args) {
@@ -2598,8 +2587,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(pings_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), pings_sent);
 }
 
 void SafeBrowsingUIHandler::GetPGResponses(const base::Value::List& args) {
@@ -2617,8 +2605,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(responses_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), responses_sent);
 }
 
 void SafeBrowsingUIHandler::GetRTLookupPings(const base::Value::List& args) {
@@ -2637,8 +2624,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(pings_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), pings_sent);
 }
 
 void SafeBrowsingUIHandler::GetRTLookupResponses(
@@ -2657,8 +2643,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(responses_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), responses_sent);
 }
 
 void SafeBrowsingUIHandler::GetReferrerChain(const base::Value::List& args) {
@@ -2698,13 +2683,14 @@
 }
 
 void SafeBrowsingUIHandler::GetReferringAppInfo(const base::Value::List& args) {
-  base::Value referring_app_value;
 #if BUILDFLAG(IS_ANDROID)
+  base::Value::Dict referring_app_value;
   LoginReputationClientRequest::ReferringAppInfo info =
       WebUIInfoSingleton::GetInstance()->GetReferringAppInfo(
           web_ui()->GetWebContents());
   referring_app_value = SerializeReferringAppInfo(info);
 #else
+  base::Value referring_app_value;
   referring_app_value = base::Value("Not supported on current platform.");
 #endif
   std::string referring_app_serialized;
@@ -2729,8 +2715,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(reporting_events)));
+  ResolveJavascriptCallback(base::Value(callback_id), reporting_events);
 }
 
 void SafeBrowsingUIHandler::GetLogMessages(const base::Value::List& args) {
@@ -2746,8 +2731,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(messages_received)));
+  ResolveJavascriptCallback(base::Value(callback_id), messages_received);
 }
 
 void SafeBrowsingUIHandler::GetDeepScans(const base::Value::List& args) {
@@ -2763,8 +2747,7 @@
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(pings_sent)));
+  ResolveJavascriptCallback(base::Value(callback_id), pings_sent);
 }
 
 void SafeBrowsingUIHandler::NotifyDownloadUrlCheckedJsListener(
@@ -2839,7 +2822,7 @@
   request_list.Append(SerializePGPing(request));
 
   AllowJavascript();
-  FireWebUIListener("pg-pings-update", base::Value(std::move(request_list)));
+  FireWebUIListener("pg-pings-update", request_list);
 }
 
 void SafeBrowsingUIHandler::NotifyPGResponseJsListener(
@@ -2850,8 +2833,7 @@
   response_list.Append(SerializePGResponse(response));
 
   AllowJavascript();
-  FireWebUIListener("pg-responses-update",
-                    base::Value(std::move(response_list)));
+  FireWebUIListener("pg-responses-update", response_list);
 }
 
 void SafeBrowsingUIHandler::NotifyRTLookupPingJsListener(
@@ -2862,8 +2844,7 @@
   request_list.Append(SerializeRTLookupPing(request));
 
   AllowJavascript();
-  FireWebUIListener("rt-lookup-pings-update",
-                    base::Value(std::move(request_list)));
+  FireWebUIListener("rt-lookup-pings-update", request_list);
 }
 
 void SafeBrowsingUIHandler::NotifyRTLookupResponseJsListener(
@@ -2874,8 +2855,7 @@
   response_list.Append(SerializeRTLookupResponse(response));
 
   AllowJavascript();
-  FireWebUIListener("rt-lookup-responses-update",
-                    base::Value(std::move(response_list)));
+  FireWebUIListener("rt-lookup-responses-update", response_list);
 }
 
 void SafeBrowsingUIHandler::NotifyLogMessageJsListener(
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index b402e3c..6a09371 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -209,33 +209,33 @@
 
 // Adds the name and the enabled/disabled status of a given feature.
 void AddFeatureAndAvailability(const base::Feature* exp_feature,
-                               base::ListValue* param_list) {
-  param_list->Append(base::Value(exp_feature->name));
+                               base::Value::List* param_list) {
+  param_list->Append(exp_feature->name);
   if (base::FeatureList::IsEnabled(*exp_feature)) {
-    param_list->Append(base::Value("Enabled"));
+    param_list->Append("Enabled");
   } else {
-    param_list->Append(base::Value("Disabled"));
+    param_list->Append("Disabled");
   }
 }
 }  // namespace
 
 // Returns the list of the experimental features that are enabled or disabled,
 // as part of currently running Safe Browsing experiments.
-base::ListValue GetFeatureStatusList() {
-  base::ListValue param_list;
+base::Value::List GetFeatureStatusList() {
+  base::Value::List param_list;
   for (const auto& feature_status : kExperimentalFeatures) {
     if (feature_status.show_state)
       AddFeatureAndAvailability(feature_status.feature, &param_list);
   }
 
   // Manually add experimental features that we want param values for.
-  param_list.Append(base::Value(variations::GetVariationParamValueByFeature(
+  param_list.Append(variations::GetVariationParamValueByFeature(
       safe_browsing::kClientSideDetectionModelTag,
-      kClientSideDetectionTagParamName)));
-  param_list.Append(base::Value(kClientSideDetectionModelTag.name));
-  param_list.Append(base::Value(variations::GetVariationParamValueByFeature(
-      kFileTypePoliciesTag, kFileTypePoliciesTagParamName)));
-  param_list.Append(base::Value(kFileTypePoliciesTag.name));
+      kClientSideDetectionTagParamName));
+  param_list.Append(kClientSideDetectionModelTag.name);
+  param_list.Append(variations::GetVariationParamValueByFeature(
+      kFileTypePoliciesTag, kFileTypePoliciesTagParamName));
+  param_list.Append(kFileTypePoliciesTag.name);
 
   return param_list;
 }
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h
index 8c01cc8..951fea23 100644
--- a/components/safe_browsing/core/common/features.h
+++ b/components/safe_browsing/core/common/features.h
@@ -11,10 +11,6 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/values.h"
 
-namespace base {
-class ListValue;
-}  // namespace base
-
 namespace safe_browsing {
 // Features list, in alphabetical order.
 
@@ -181,7 +177,7 @@
 // Controls whether we send visual features in CSPP pings.
 extern const base::Feature kVisualFeaturesInCsppPings;
 
-base::ListValue GetFeatureStatusList();
+base::Value::List GetFeatureStatusList();
 
 // Returns the tag used for Client Side Phishing Detection models, as
 // computed from the current feature flags.
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.cc b/components/safe_browsing/core/common/safe_browsing_prefs.cc
index cbe84f00..83fc75c 100644
--- a/components/safe_browsing/core/common/safe_browsing_prefs.cc
+++ b/components/safe_browsing/core/common/safe_browsing_prefs.cc
@@ -282,8 +282,8 @@
   prefs->SetBoolean(prefs::kSafeBrowsingSawInterstitialScoutReporting, true);
 }
 
-base::ListValue GetSafeBrowsingPreferencesList(PrefService* prefs) {
-  base::ListValue preferences_list;
+base::Value::List GetSafeBrowsingPreferencesList(PrefService* prefs) {
+  base::Value::List preferences_list;
 
   const char* safe_browsing_preferences[] = {
       prefs::kSafeBrowsingEnabled,
@@ -293,15 +293,15 @@
   // Add the status of the preferences if they are Enabled or Disabled for the
   // user.
   for (const char* preference : safe_browsing_preferences) {
-    preferences_list.Append(base::Value(preference));
+    preferences_list.Append(preference);
     bool enabled = prefs->GetBoolean(preference);
-    preferences_list.Append(base::Value(enabled ? "Enabled" : "Disabled"));
+    preferences_list.Append(enabled ? "Enabled" : "Disabled");
   }
   return preferences_list;
 }
 
-base::ListValue GetSafeBrowsingPoliciesList(PrefService* prefs) {
-  base::ListValue preferences_list;
+base::Value::List GetSafeBrowsingPoliciesList(PrefService* prefs) {
+  base::Value::List preferences_list;
   const base::Value::List& allowlist_domains =
       prefs->GetValueList(prefs::kSafeBrowsingAllowlistDomains);
   std::vector<std::string> domain_list;
@@ -310,16 +310,14 @@
   for (const auto& domain : domain_list) {
     domains = domains + " " + domain;
   }
-  preferences_list.Append(base::Value(domains));
-  preferences_list.Append(base::Value(prefs::kSafeBrowsingAllowlistDomains));
-  preferences_list.Append(base::Value(
-      prefs->GetString(prefs::kPasswordProtectionChangePasswordURL)));
+  preferences_list.Append(domains);
+  preferences_list.Append(prefs::kSafeBrowsingAllowlistDomains);
   preferences_list.Append(
-      base::Value(prefs::kPasswordProtectionChangePasswordURL));
-  preferences_list.Append(base::Value(base::NumberToString(
-      prefs->GetInteger(prefs::kPasswordProtectionWarningTrigger))));
-  preferences_list.Append(
-      base::Value(prefs::kPasswordProtectionWarningTrigger));
+      prefs->GetString(prefs::kPasswordProtectionChangePasswordURL));
+  preferences_list.Append(prefs::kPasswordProtectionChangePasswordURL);
+  preferences_list.Append(base::NumberToString(
+      prefs->GetInteger(prefs::kPasswordProtectionWarningTrigger)));
+  preferences_list.Append(prefs::kPasswordProtectionWarningTrigger);
 
   std::vector<GURL> login_urls_list;
   GetPasswordProtectionLoginURLsPref(*prefs, &login_urls_list);
@@ -327,8 +325,8 @@
   for (const auto& login_url : login_urls_list) {
     login_urls = login_urls + " " + login_url.spec();
   }
-  preferences_list.Append(base::Value(login_urls));
-  preferences_list.Append(base::Value(prefs::kPasswordProtectionLoginURLs));
+  preferences_list.Append(login_urls);
+  preferences_list.Append(prefs::kPasswordProtectionLoginURLs);
   return preferences_list;
 }
 
diff --git a/components/safe_browsing/core/common/safe_browsing_prefs.h b/components/safe_browsing/core/common/safe_browsing_prefs.h
index 52ad7e2..3b952c99 100644
--- a/components/safe_browsing/core/common/safe_browsing_prefs.h
+++ b/components/safe_browsing/core/common/safe_browsing_prefs.h
@@ -293,12 +293,12 @@
 // Returns a list of preferences to be shown in chrome://safe-browsing. The
 // preferences are passed as an alternating sequence of preference names and
 // values represented as strings.
-base::ListValue GetSafeBrowsingPreferencesList(PrefService* prefs);
+base::Value::List GetSafeBrowsingPreferencesList(PrefService* prefs);
 
 // Returns a list of policies to be shown in chrome://safe-browsing. The
 // policies are passed as an alternating sequence of policy names and
 // values represented as strings.
-base::ListValue GetSafeBrowsingPoliciesList(PrefService* prefs);
+base::Value::List GetSafeBrowsingPoliciesList(PrefService* prefs);
 
 // Returns a list of valid domains that Safe Browsing service trusts.
 void GetSafeBrowsingAllowlistDomainsPref(
diff --git a/components/search/ntp_features.cc b/components/search/ntp_features.cc
index a642e5a..cea5d0cd 100644
--- a/components/search/ntp_features.cc
+++ b/components/search/ntp_features.cc
@@ -56,7 +56,7 @@
 
 // If enabled, chrome cart module will be shown.
 const base::Feature kNtpChromeCartModule{"NtpChromeCartModule",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
+                                         base::FEATURE_ENABLED_BY_DEFAULT};
 #if !defined(OFFICIAL_BUILD)
 // If enabled, dummy modules will be shown.
 const base::Feature kNtpDummyModules{"NtpDummyModules",
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 2acb1bb..a6102e51 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -930,6 +930,13 @@
   }
 }
 
+bool TemplateURLService::IsKeywordFromStarterPackTabSearch(
+    const std::u16string& keyword) {
+  const TemplateURL* turl = GetTemplateURLForKeyword(keyword);
+
+  return (turl && turl->starter_pack_id() == TemplateURLStarterPackData::kTabs);
+}
+
 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
   model_observers_.AddObserver(observer);
 }
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h
index 1f4e21c..69c046bd 100644
--- a/components/search_engines/template_url_service.h
+++ b/components/search_engines/template_url_service.h
@@ -351,6 +351,12 @@
   // the default search engine entry.
   void RepairStarterPackEngines();
 
+  // Looks up `keyword` and determines whether the best TemplateURL for it is
+  // associated with the starter pack tab search engine.  Returns false if there
+  // is no matching TURL for the given keyword or if it is associated with
+  // another search engine.
+  bool IsKeywordFromStarterPackTabSearch(const std::u16string& keyword);
+
   // Observers used to listen for changes to the model.
   // TemplateURLService does NOT delete the observers when deleted.
   void AddObserver(TemplateURLServiceObserver* observer);
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index ce4f2066..4b04265 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -65,7 +65,7 @@
 }
 
 void AddSection(base::Value::List& parent_list,
-                base::Value section_content,
+                base::Value::List section_content,
                 const std::string& title) {
   base::Value::Dict section;
   section.Set("title", title);
@@ -353,15 +353,15 @@
   if (signin_observers_.empty())
     return;
 
-  base::Value signin_status_value = signin_status_.ToValue(
+  base::Value::Dict signin_status_value = signin_status_.ToValue(
       identity_manager_, signin_error_controller_, client_,
       account_consistency_, account_reconcilor_);
 
   for (auto& observer : signin_observers_)
-    observer.OnSigninStateChanged(&signin_status_value);
+    observer.OnSigninStateChanged(signin_status_value);
 }
 
-base::Value AboutSigninInternals::GetSigninStatus() {
+base::Value::Dict AboutSigninInternals::GetSigninStatus() {
   return signin_status_.ToValue(identity_manager_, signin_error_controller_,
                                 client_, account_consistency_,
                                 account_reconcilor_);
@@ -497,10 +497,9 @@
 
   base::Value::Dict cookie_status_dict;
   cookie_status_dict.Set("cookie_info", std::move(cookie_info));
-  base::Value cookie_status(std::move(cookie_status_dict));
   // Update the observers that the cookie's accounts are updated.
   for (auto& observer : signin_observers_)
-    observer.OnCookieAccountsFetched(&cookie_status);
+    observer.OnCookieAccountsFetched(cookie_status_dict);
 }
 
 AboutSigninInternals::TokenInfo::TokenInfo(const std::string& consumer_id,
@@ -522,7 +521,7 @@
 
 void AboutSigninInternals::TokenInfo::Invalidate() { removed_ = true; }
 
-base::Value AboutSigninInternals::TokenInfo::ToValue() const {
+base::Value::Dict AboutSigninInternals::TokenInfo::ToValue() const {
   base::Value::Dict token_info;
   token_info.Set("service", consumer_id);
 
@@ -563,7 +562,7 @@
     token_info.Set("status", "Waiting for response");
   }
 
-  return base::Value(std::move(token_info));
+  return token_info;
 }
 
 AboutSigninInternals::RefreshTokenEvent::RefreshTokenEvent()
@@ -606,7 +605,7 @@
   refresh_token_events.push_back(event);
 }
 
-base::Value AboutSigninInternals::SigninStatus::ToValue(
+base::Value::Dict AboutSigninInternals::SigninStatus::ToValue(
     signin::IdentityManager* identity_manager,
     SigninErrorController* signin_error_controller,
     SigninClient* signin_client,
@@ -664,8 +663,7 @@
         basic_info, "Account Reconcilor blocked",
         account_reconcilor->IsReconcileBlocked() ? "True" : "False");
 
-    AddSection(signin_info, base::Value(std::move(basic_info)),
-               "Basic Information");
+    AddSection(signin_info, std::move(basic_info), "Basic Information");
   }
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
@@ -707,8 +705,7 @@
                       base::TimeToISO8601(next_retry_time), "");
     }
 
-    AddSection(signin_info, base::Value(std::move(detailed_info)),
-               "Last Signin Details");
+    AddSection(signin_info, std::move(detailed_info), "Last Signin Details");
   }
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -723,8 +720,7 @@
     for (const std::unique_ptr<TokenInfo>& token : it.second)
       token_details.Append(token->ToValue());
 
-    AddSection(token_info, base::Value(std::move(token_details)),
-               it.first.ToString());
+    AddSection(token_info, std::move(token_details), it.first.ToString());
   }
   signin_status.Set("token_info", std::move(token_info));
 
@@ -766,5 +762,5 @@
   signin_status.Set("refreshTokenEvents",
                     std::move(refresh_token_events_value));
 
-  return base::Value(std::move(signin_status));
+  return signin_status;
 }
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h
index a846081..ef2f9191 100644
--- a/components/signin/core/browser/about_signin_internals.h
+++ b/components/signin/core/browser/about_signin_internals.h
@@ -49,10 +49,10 @@
    public:
     // |info| will contain the dictionary of signin_status_ values as indicated
     // in the comments for GetSigninStatus() below.
-    virtual void OnSigninStateChanged(const base::Value* info) = 0;
+    virtual void OnSigninStateChanged(const base::Value::Dict& info) = 0;
 
     // Notification that the cookie accounts are ready to be displayed.
-    virtual void OnCookieAccountsFetched(const base::Value* info) = 0;
+    virtual void OnCookieAccountsFetched(const base::Value::Dict& info) = 0;
   };
 
   AboutSigninInternals(signin::IdentityManager* identity_manager,
@@ -97,7 +97,7 @@
   //     [ List of {"name": "foo-name", "token" : "foo-token",
   //                 "status": "foo_stat", "time" : "foo_time"} elems]
   //  }
-  base::Value GetSigninStatus();
+  base::Value::Dict GetSigninStatus();
 
   // signin::IdentityManager::Observer implementations.
   void OnAccountsInCookieUpdated(
@@ -109,7 +109,7 @@
   struct TokenInfo {
     TokenInfo(const std::string& consumer_id, const signin::ScopeSet& scopes);
     ~TokenInfo();
-    base::Value ToValue() const;
+    base::Value::Dict ToValue() const;
 
     static bool LessThan(const std::unique_ptr<TokenInfo>& a,
                          const std::unique_ptr<TokenInfo>& b);
@@ -182,11 +182,12 @@
     //                           "status" : request status} elems]
     //       }],
     //  }
-    base::Value ToValue(signin::IdentityManager* identity_manager,
-                        SigninErrorController* signin_error_controller,
-                        SigninClient* signin_client,
-                        signin::AccountConsistencyMethod account_consistency,
-                        AccountReconcilor* account_reconcilor);
+    base::Value::Dict ToValue(
+        signin::IdentityManager* identity_manager,
+        SigninErrorController* signin_error_controller,
+        SigninClient* signin_client,
+        signin::AccountConsistencyMethod account_consistency,
+        AccountReconcilor* account_reconcilor);
   };
 
   // IdentityManager::DiagnosticsObserver implementations.
diff --git a/components/update_client/component_unpacker.cc b/components/update_client/component_unpacker.cc
index dda9ed5..7097aa5 100644
--- a/components/update_client/component_unpacker.cc
+++ b/components/update_client/component_unpacker.cc
@@ -102,28 +102,27 @@
   BeginPatching();
 }
 
-bool ComponentUnpacker::BeginPatching() {
+void ComponentUnpacker::BeginPatching() {
   if (is_delta_) {  // Package is a diff package.
     // Use a different temp directory for the patch output files.
     if (!base::CreateNewTempDirectory(base::FilePath::StringType(),
                                       &unpack_path_)) {
-      error_ = UnpackerError::kUnzipPathError;
-      return false;
+      base::SequencedTaskRunnerHandle::Get()->PostTask(
+          FROM_HERE, base::BindOnce(&ComponentUnpacker::EndPatching, this,
+                                    UnpackerError::kUnzipPathError, 0));
+      return;
     }
     patcher_ = base::MakeRefCounted<ComponentPatcher>(
         unpack_diff_path_, unpack_path_, installer_, patcher_tool_);
     base::SequencedTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::BindOnce(&ComponentPatcher::Start, patcher_,
-                       base::BindOnce(&ComponentUnpacker::EndPatching,
-                                      scoped_refptr<ComponentUnpacker>(this))));
+                       base::BindOnce(&ComponentUnpacker::EndPatching, this)));
   } else {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&ComponentUnpacker::EndPatching,
-                                  scoped_refptr<ComponentUnpacker>(this),
+        FROM_HERE, base::BindOnce(&ComponentUnpacker::EndPatching, this,
                                   UnpackerError::kNone, 0));
   }
-  return true;
 }
 
 void ComponentUnpacker::EndPatching(UnpackerError error, int extended_error) {
diff --git a/components/update_client/component_unpacker.h b/components/update_client/component_unpacker.h
index f802d0e..1a735471 100644
--- a/components/update_client/component_unpacker.h
+++ b/components/update_client/component_unpacker.h
@@ -117,9 +117,8 @@
   void EndUnzipping(bool error);
 
   // The third step is to optionally patch files - this is a no-op for full
-  // (non-differential) updates. This step is asynchronous. Returns false if an
-  // error is encountered.
-  bool BeginPatching();
+  // (non-differential) updates. This step is asynchronous.
+  void BeginPatching();
   void EndPatching(UnpackerError error, int extended_error);
 
   // The final step is to do clean-up for things that can't be tidied as we go.
diff --git a/components/viz/service/debugger/viz_debugger.h b/components/viz/service/debugger/viz_debugger.h
index d5ad5ad..26952cc 100644
--- a/components/viz/service/debugger/viz_debugger.h
+++ b/components/viz/service/debugger/viz_debugger.h
@@ -80,7 +80,7 @@
 
   ~VizDebugger();
 
-  struct BufferInfo {
+  struct VIZ_SERVICE_EXPORT BufferInfo {
     BufferInfo();
     ~BufferInfo();
     BufferInfo(const BufferInfo& a);
diff --git a/components/viz/service/debugger/viz_debugger_unittest.cc b/components/viz/service/debugger/viz_debugger_unittest.cc
index 67c977b..0c8a7ef0 100644
--- a/components/viz/service/debugger/viz_debugger_unittest.cc
+++ b/components/viz/service/debugger/viz_debugger_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 #include <stddef.h>
 
+#include <cstddef>
 #include <cstdio>
 #include <unordered_map>
 #include <utility>
@@ -43,7 +44,9 @@
 
 bool VizDebuggerInternal::Reset() {
   submission_count_ = 0;
+  buffer_id = 0;
   draw_rect_calls_.clear();
+  buffers_.clear();
   draw_text_calls_.clear();
   logs_.clear();
   last_sent_source_count_ = 0;
@@ -112,6 +115,7 @@
   void GetFrameData() {
     sources_.clear();
     draw_calls_.clear();
+    buffers_.clear();
     log_calls_.clear();
     draw_text_calls_.clear();
     GetInternal()->common_lock_.Acquire();
@@ -193,13 +197,46 @@
       float pos_y =
           list_pos->GetListDeprecated()[1].GetIfDouble().value_or(kNoVal);
 
-      VizDebuggerInternal::DrawCall draw_call(draw_index, source_index, option,
-                                              gfx::Size(size_x, size_y),
-                                              gfx::Vector2dF(pos_x, pos_y), -1);
+      const base::Value* buffer_id = local_dict.FindKey("buff_id");
+
+      VizDebuggerInternal::DrawCall draw_call(
+          draw_index, source_index, option, gfx::Size(size_x, size_y),
+          gfx::Vector2dF(pos_x, pos_y), buffer_id ? buffer_id->GetInt() : -1);
 
       draw_calls_.push_back(draw_call);
     }
 
+    base::Value* buffer_map_dict = global_dict->FindKey("buff_map");
+    if (buffer_map_dict) {
+      for (base::Value::Dict::iterator itr = buffer_map_dict->GetDict().begin();
+           itr != buffer_map_dict->GetDict().end(); itr++) {
+        base::Value* buffer_dict = buffer_map_dict->FindKey(itr->first);
+        EXPECT_TRUE(buffer_dict);
+        int width = buffer_dict->FindKey("width")->GetIfInt().value_or(kNoVal);
+        int height =
+            buffer_dict->FindKey("height")->GetIfInt().value_or(kNoVal);
+        base::Value* buffer_info = buffer_dict->FindKey("buffer");
+        EXPECT_TRUE(buffer_info->is_list());
+        VizDebuggerInternal::BufferInfo buff;
+        buff.width = width;
+        buff.height = height;
+        buff.buffer.resize(width * height);
+        for (size_t i = 0; i < buffer_info->GetList().size() / 4; i++) {
+          uint8_t temp1 = buffer_info->GetList()[i * 4].GetInt();
+          uint8_t temp2 = buffer_info->GetList()[i * 4 + 1].GetInt();
+          uint8_t temp3 = buffer_info->GetList()[i * 4 + 2].GetInt();
+          uint8_t temp4 = buffer_info->GetList()[i * 4 + 3].GetInt();
+          buff.buffer[i] = {temp1, temp2, temp3, temp4};
+        }
+        int id;
+        base::StringToInt(itr->first, &id);
+        VizDebuggerInternal::Buffer buffer;
+        buffer.id = id;
+        buffer.buffer_info = buff;
+        buffers_.push_back(buffer);
+      }
+    }
+
     base::Value* text_call_list = global_dict->FindListKey("text");
     EXPECT_TRUE(text_call_list->is_list());
 
@@ -251,6 +288,7 @@
   int window_y_ = 256;
   std::vector<StaticSource> sources_;
   std::vector<VizDebuggerInternal::DrawCall> draw_calls_;
+  std::vector<VizDebuggerInternal::Buffer> buffers_;
   std::vector<VizDebuggerInternal::LogCall> log_calls_;
   std::vector<VizDebuggerInternal::DrawTextCall> draw_text_calls_;
 };
@@ -436,6 +474,302 @@
   EXPECT_EQ(1, count_b);
 }
 
+// This tests passing a single buffer synchronously into the visual debuggeer
+TEST_F(VisualDebuggerTest, SingleBufferSync) {
+  const char kAnnoRect[] = "annorect";
+  const gfx::Rect kTestRect = gfx::Rect(12, 34, 56, 78);
+  static const int kNumFrames = 1;
+  GetInternal()->ForceEnabled();
+  VizDebuggerInternal::BufferInfo buffer_info;
+  buffer_info.width = 4;
+  buffer_info.height = 4;
+  buffer_info.buffer.resize(buffer_info.width * buffer_info.height);
+  for (int i = 0; i < buffer_info.height * buffer_info.width; i++) {
+    // Random numbers between 0-255 for RGBA values
+    uint8_t temp1 = 123;
+    uint8_t temp2 = 140;
+    uint8_t temp3 = 203;
+    uint8_t temp4 = 255;
+    buffer_info.buffer[i] = {temp1, temp2, temp3, temp4};
+  }
+  VizDebuggerInternal::Buffer buffer;
+  buffer.id = 0;
+  buffer.buffer_info = buffer_info;
+  for (uint64_t frame_idx = 0; frame_idx < kNumFrames; frame_idx++) {
+    SetFilter({TestFilter({""})});
+
+    static const int kNumSubmission = 1;
+    int id = 0;
+    DBG_COMPLETE_BUFFERS(id, buffer.buffer_info);
+    DBG_DRAW_RECT_BUFF(kAnnoRect, kTestRect, &id);
+
+    GetFrameData();
+
+    EXPECT_EQ(counter_, frame_idx);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(draw_calls_.size(), static_cast<size_t>(kNumSubmission));
+    EXPECT_EQ(buffers_.size(), static_cast<size_t>(kNumSubmission));
+
+    if (frame_idx == 0) {
+      EXPECT_EQ(sources_.size(), 1u);
+      EXPECT_EQ(sources_[0].func, "TestBody");
+      EXPECT_EQ(sources_[0].file, __FILE__);
+      EXPECT_EQ(sources_[0].anno, kAnnoRect);
+    } else {
+      // After the first frame there are no new sources in the loop.
+      EXPECT_EQ(sources_.size(), 0u);
+    }
+
+    EXPECT_EQ(draw_calls_[0].buff_id, 0);
+
+    EXPECT_EQ(buffers_[0].buffer_info.width, buffer.buffer_info.width);
+    EXPECT_EQ(buffers_[0].buffer_info.height, buffer.buffer_info.height);
+    for (int j = 0;
+         j < buffers_[0].buffer_info.width * buffers_[0].buffer_info.height;
+         j++) {
+      EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_r),
+                static_cast<int>(buffer.buffer_info.buffer[j].color_r));
+      EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_g),
+                static_cast<int>(buffer.buffer_info.buffer[j].color_g));
+      EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_b),
+                static_cast<int>(buffer.buffer_info.buffer[j].color_b));
+      EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_a),
+                static_cast<int>(buffer.buffer_info.buffer[j].color_a));
+    }
+  }
+}
+
+// This tests passing multiple buffers into the visual debugger synchronously
+TEST_F(VisualDebuggerTest, MultipleBuffersSync) {
+  const char kAnnoRect[] = "annorect";
+  const gfx::Rect kTestRect = gfx::Rect(12, 34, 56, 78);
+  static const int kNumFrames = 1;
+  GetInternal()->ForceEnabled();
+  GetInternal()->Reset();
+  VizDebuggerInternal::BufferInfo buffer_info;
+  buffer_info.width = 4;
+  buffer_info.height = 4;
+  buffer_info.buffer.resize(buffer_info.width * buffer_info.height);
+  for (int i = 0; i < buffer_info.height * buffer_info.width; i++) {
+    // Random numbers between 0-255 for RGBA values
+    uint8_t temp1 = 123;
+    uint8_t temp2 = 140;
+    uint8_t temp3 = 203;
+    uint8_t temp4 = 255;
+    buffer_info.buffer[i] = {temp1, temp2, temp3, temp4};
+  }
+  VizDebuggerInternal::Buffer buffer;
+  buffer.id = 0;
+  buffer.buffer_info = buffer_info;
+  for (uint64_t frame_idx = 0; frame_idx < kNumFrames; frame_idx++) {
+    SetFilter({TestFilter({""})});
+
+    static const int kNumSubmission = 8;
+    for (int i = 0; i < kNumSubmission; i++) {
+      int id = i;
+      DBG_COMPLETE_BUFFERS(id, buffer.buffer_info);
+      DBG_DRAW_RECT_BUFF(kAnnoRect, kTestRect, &id);
+    }
+
+    GetFrameData();
+
+    EXPECT_EQ(counter_, frame_idx);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(draw_calls_.size(), static_cast<size_t>(kNumSubmission));
+    EXPECT_EQ(buffers_.size(), static_cast<size_t>(kNumSubmission));
+
+    if (frame_idx == 0) {
+      EXPECT_EQ(sources_.size(), 1u);
+      EXPECT_EQ(sources_[0].func, "TestBody");
+      EXPECT_EQ(sources_[0].file, __FILE__);
+      EXPECT_EQ(sources_[0].anno, kAnnoRect);
+    } else {
+      // After the first frame there are no new sources in the loop.
+      EXPECT_EQ(sources_.size(), 0u);
+    }
+
+    for (int i = 0; i < kNumSubmission; i++) {
+      EXPECT_EQ(draw_calls_[i].buff_id, i);
+
+      EXPECT_EQ(buffers_[i].buffer_info.width, buffer.buffer_info.width);
+      EXPECT_EQ(buffers_[i].buffer_info.height, buffer.buffer_info.height);
+      for (int j = 0;
+           j < buffers_[i].buffer_info.width * buffers_[i].buffer_info.height;
+           j++) {
+        EXPECT_EQ(static_cast<int>(buffers_[i].buffer_info.buffer[j].color_r),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_r));
+        EXPECT_EQ(static_cast<int>(buffers_[i].buffer_info.buffer[j].color_g),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_g));
+        EXPECT_EQ(static_cast<int>(buffers_[i].buffer_info.buffer[j].color_b),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_b));
+        EXPECT_EQ(static_cast<int>(buffers_[i].buffer_info.buffer[j].color_a),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_a));
+      }
+    }
+  }
+}
+
+// This tests passing a single buffer into the visual debugger asynchronously
+TEST_F(VisualDebuggerTest, SingleBufferAsync) {
+  const char kAnnoRect[] = "annorect";
+  const gfx::Rect kTestRect = gfx::Rect(12, 34, 56, 78);
+  static const int kNumFrames = 2;
+  GetInternal()->ForceEnabled();
+  GetInternal()->Reset();
+  VizDebuggerInternal::BufferInfo buffer_info;
+  buffer_info.width = 4;
+  buffer_info.height = 4;
+  buffer_info.buffer.resize(buffer_info.width * buffer_info.height);
+  for (int i = 0; i < buffer_info.height * buffer_info.width; i++) {
+    // Random numbers between 0-255 for RGBA values
+    uint8_t temp1 = 123;
+    uint8_t temp2 = 140;
+    uint8_t temp3 = 203;
+    uint8_t temp4 = 255;
+    buffer_info.buffer[i] = {temp1, temp2, temp3, temp4};
+  }
+  VizDebuggerInternal::Buffer buffer;
+  buffer.id = 0;
+  buffer.buffer_info = buffer_info;
+  for (uint64_t frame_idx = 0; frame_idx < kNumFrames; frame_idx++) {
+    SetFilter({TestFilter({""})});
+
+    static const int kNumSubmission = 1;
+    static std::vector<VizDebuggerInternal::Buffer> previous_textures;
+    for (auto&& each : previous_textures) {
+      DBG_COMPLETE_BUFFERS(each.id, each.buffer_info)
+    }
+
+    int id = 0;
+    DBG_DRAW_RECT_BUFF(kAnnoRect, kTestRect, &id);
+    buffer.id = id;
+    previous_textures.emplace_back(buffer);
+
+    GetFrameData();
+
+    EXPECT_EQ(counter_, frame_idx);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(draw_calls_.size(), static_cast<size_t>(kNumSubmission));
+
+    if (frame_idx == 0) {
+      EXPECT_EQ(sources_.size(), 1u);
+      EXPECT_EQ(sources_[0].func, "TestBody");
+      EXPECT_EQ(sources_[0].file, __FILE__);
+      EXPECT_EQ(sources_[0].anno, kAnnoRect);
+      EXPECT_EQ(buffers_.size(), static_cast<size_t>(0));
+    } else {
+      // After the first frame there are no new sources in the loop.
+      EXPECT_EQ(sources_.size(), 0u);
+      EXPECT_EQ(buffers_.size(), static_cast<size_t>(kNumSubmission));
+      EXPECT_EQ(draw_calls_[0].buff_id, 1);
+      EXPECT_EQ(buffers_[0].buffer_info.width, buffer.buffer_info.width);
+      EXPECT_EQ(buffers_[0].buffer_info.height, buffer.buffer_info.height);
+      for (int j = 0;
+           j < buffers_[0].buffer_info.width * buffers_[0].buffer_info.height;
+           j++) {
+        EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_r),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_r));
+        EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_g),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_g));
+        EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_b),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_b));
+        EXPECT_EQ(static_cast<int>(buffers_[0].buffer_info.buffer[j].color_a),
+                  static_cast<int>(buffer.buffer_info.buffer[j].color_a));
+      }
+    }
+  }
+}
+
+// This tests passing multiple buffers into the visual debugger asynchronously
+TEST_F(VisualDebuggerTest, MultipleBuffersAsync) {
+  const char kAnnoRect[] = "annorect";
+  const gfx::Rect kTestRect = gfx::Rect(12, 34, 56, 78);
+  static const int kNumFrames = 2;
+  GetInternal()->ForceEnabled();
+  GetInternal()->Reset();
+  VizDebuggerInternal::BufferInfo buffer_info;
+  buffer_info.width = 4;
+  buffer_info.height = 4;
+  buffer_info.buffer.resize(buffer_info.width * buffer_info.height);
+  VizDebuggerInternal::Buffer buffer;
+  buffer.id = 0;
+  for (uint64_t frame_idx = 0; frame_idx < kNumFrames; frame_idx++) {
+    SetFilter({TestFilter({""})});
+
+    static const int kNumSubmission = 8;
+    static std::vector<VizDebuggerInternal::Buffer> previous_textures;
+    static std::vector<VizDebuggerInternal::Buffer> test_buffers;
+    for (auto&& each : previous_textures) {
+      for (int i = 0; i < buffer_info.width * buffer_info.height; i++) {
+        // Random numbers between 0-255 for RGBA values
+        uint8_t temp1 = (each.id + 15) * 11231;
+        uint8_t temp2 = (each.id + 24) * 32461231;
+        uint8_t temp3 = (each.id + 523) * 72321231;
+        uint8_t temp4 = (each.id + 52) * 321231;
+        buffer_info.buffer[i] = {temp1, temp2, temp3, temp4};
+      }
+      buffer.id = each.id;
+      buffer.buffer_info = buffer_info;
+      test_buffers.emplace(test_buffers.begin(), buffer);
+      DBG_COMPLETE_BUFFERS(buffer.id, buffer.buffer_info);
+    }
+    previous_textures.resize(kNumSubmission);
+    previous_textures.clear();
+    for (int i = 0; i < kNumSubmission; i++) {
+      int id = i;
+      buffer.id = id;
+      DBG_DRAW_RECT_BUFF(kAnnoRect, kTestRect, &id);
+      buffer.buffer_info = buffer_info;
+      previous_textures.emplace(previous_textures.end() - i, buffer);
+    }
+
+    GetFrameData();
+
+    EXPECT_EQ(counter_, frame_idx);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(window_x_, 256);
+    EXPECT_EQ(draw_calls_.size(), static_cast<size_t>(kNumSubmission));
+
+    if (frame_idx == 0) {
+      EXPECT_EQ(sources_.size(), 1u);
+      EXPECT_EQ(sources_[0].func, "TestBody");
+      EXPECT_EQ(sources_[0].file, __FILE__);
+      EXPECT_EQ(sources_[0].anno, kAnnoRect);
+      EXPECT_EQ(buffers_.size(), static_cast<size_t>(0));
+    } else {
+      // After the first frame there are no new sources in the loop
+      EXPECT_EQ(sources_.size(), 0u);
+      EXPECT_EQ(buffers_.size(), static_cast<size_t>(kNumSubmission));
+      for (int i = 0; i < kNumSubmission; i++) {
+        EXPECT_EQ(draw_calls_[i].buff_id, i + 8);
+        EXPECT_EQ(buffers_[i].buffer_info.width,
+                  test_buffers[i].buffer_info.width);
+        EXPECT_EQ(buffers_[i].buffer_info.height,
+                  test_buffers[i].buffer_info.height);
+        for (int j = 0;
+             j < buffers_[i].buffer_info.width * buffers_[i].buffer_info.height;
+             j++) {
+          EXPECT_EQ(
+              static_cast<int>(buffers_[i].buffer_info.buffer[j].color_r),
+              static_cast<int>(test_buffers[i].buffer_info.buffer[j].color_r));
+          EXPECT_EQ(
+              static_cast<int>(buffers_[i].buffer_info.buffer[j].color_g),
+              static_cast<int>(test_buffers[i].buffer_info.buffer[j].color_g));
+          EXPECT_EQ(
+              static_cast<int>(buffers_[i].buffer_info.buffer[j].color_b),
+              static_cast<int>(test_buffers[i].buffer_info.buffer[j].color_b));
+          EXPECT_EQ(
+              static_cast<int>(buffers_[i].buffer_info.buffer[j].color_a),
+              static_cast<int>(test_buffers[i].buffer_info.buffer[j].color_a));
+        }
+      }
+    }
+  }
+}
+
 }  // namespace
 }  // namespace viz
 #else  // VIZ_DEBUGGER_IS_ON()
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index 3365098d..faa97e8 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -273,39 +273,9 @@
 void GetVideoCapabilities(const gpu::GpuPreferences& gpu_preferences,
                           const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
                           gpu::GPUInfo* gpu_info) {
-  // Due to https://crbug.com/709631, we don't want to query Android video
-  // decode/encode capabilities during startup. The renderer needs this info
-  // though, so assume some baseline capabilities.
-#if BUILDFLAG(IS_ANDROID)
-  // Note: Video encoding on Android relies on MediaCodec, so all cases
-  // where it's disabled for decoding it is also disabled for encoding.
-  if (gpu_preferences.disable_accelerated_video_decode ||
-      gpu_preferences.disable_accelerated_video_encode) {
-    return;
-  }
-
-  auto& encoding_profiles =
-      gpu_info->video_encode_accelerator_supported_profiles;
-
-  gpu::VideoEncodeAcceleratorSupportedProfile vea_profile;
-  vea_profile.max_resolution = gfx::Size(1280, 720);
-  vea_profile.max_framerate_numerator = 30;
-  vea_profile.max_framerate_denominator = 1;
-
-  if (media::MediaCodecUtil::IsVp8EncoderAvailable()) {
-    vea_profile.profile = gpu::VP8PROFILE_ANY;
-    encoding_profiles.push_back(vea_profile);
-  }
-
-#if BUILDFLAG(USE_PROPRIETARY_CODECS)
-  vea_profile.profile = gpu::H264PROFILE_BASELINE;
-  encoding_profiles.push_back(vea_profile);
-#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
-
   // Note: Since Android doesn't have to support PPAPI/Flash, we have not
   // returned the decoder profiles here since https://crrev.com/665999.
-#else   // BUILDFLAG(IS_ANDROID)
-
+#if !BUILDFLAG(IS_ANDROID)
   // GpuMojoMediaClient controls which decoder is actually being used, so
   // it should be the source of truth for supported profiles.
   auto maybe_decoder_configs =
@@ -317,13 +287,7 @@
         media::GpuVideoAcceleratorUtil::ConvertMediaConfigsToGpuDecodeProfiles(
             *maybe_decoder_configs);
   }
-
-  gpu_info->video_encode_accelerator_supported_profiles =
-      media::GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(
-          media::GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles(
-              gpu_preferences, gpu_workarounds, gpu_info->active_gpu(),
-              /*populate_extended_info=*/false));
-#endif  // BUILDFLAG(IS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID)
 }
 
 // Returns a callback which does a PostTask to run |callback| on the |runner|
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc
index af48bb3..8c5402c 100644
--- a/content/browser/fenced_frame/fenced_frame_browsertest.cc
+++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -484,7 +484,13 @@
 // Test that a fenced-frame does not perform any of the Android main-frame
 // viewport behaviors like zoom-out-to-fit-content or parsing the viewport
 // <meta>.
-IN_PROC_BROWSER_TEST_F(FencedFrameBrowserTest, ViewportSettings) {
+// Flaky on Mac https://crbug.com/1349900
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_ViewportSettings DISABLED_ViewportSettings
+#else
+#define MAYBE_ViewportSettings ViewportSettings
+#endif
+IN_PROC_BROWSER_TEST_F(FencedFrameBrowserTest, MAYBE_ViewportSettings) {
   ASSERT_TRUE(https_server()->Start());
   const GURL top_level_url =
       https_server()->GetURL("c.test", "/fenced_frames/viewport.html");
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 855bd71..dce664a 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -878,9 +878,7 @@
 
   GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(task));
 
-  // Since Android never had PPAPI/NaCl it doesn't initialize encoder profiles
-  // at GPU process startup. Query them now so chrome://gpu is accurate.
-#if BUILDFLAG(IS_ANDROID)
+  // Query VEA profiles to show in chrome://gpu
   auto update_vea_profiles_callback = base::BindPostTask(
       GetUIThreadTaskRunner({}),
       base::BindOnce([](const media::VideoEncodeAccelerator::SupportedProfiles&
@@ -926,7 +924,6 @@
                     std::move(vea_provider)));
           },
           std::move(update_vea_profiles_callback)));
-#endif
 }
 
 bool GpuDataManagerImplPrivate::IsEssentialGpuInfoAvailable() const {
diff --git a/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
index 020e243..10736323 100644
--- a/content/browser/renderer_host/input/scroll_latency_browsertest.cc
+++ b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -224,8 +224,8 @@
   RunMultipleWheelScroll();
 }
 
-// Disabled due to flakiness https://crbug.com/1163246.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID)
+// Disabled due to flakiness https://crbug.com/1163246 and https://crbug.com/1349901
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
 #define MAYBE_MultipleWheelScrollOnMain DISABLED_MultipleWheelScrollOnMain
 #else
 #define MAYBE_MultipleWheelScrollOnMain MultipleWheelScrollOnMain
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc
index 418a51f2..cb306cfd 100644
--- a/content/browser/renderer_host/navigation_request_browsertest.cc
+++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -3643,6 +3643,84 @@
                    ->IsViewSourceMode());
 }
 
+class NavigationRequestPrerenderBrowserTest
+    : public NavigationRequestBrowserTest {
+ public:
+  NavigationRequestPrerenderBrowserTest() {
+    prerender_helper_ =
+        std::make_unique<test::PrerenderTestHelper>(base::BindRepeating(
+            &NavigationRequestPrerenderBrowserTest::web_contents,
+            base::Unretained(this)));
+  }
+  ~NavigationRequestPrerenderBrowserTest() override = default;
+
+  NavigationRequestPrerenderBrowserTest(
+      const NavigationRequestPrerenderBrowserTest&) = delete;
+  NavigationRequestPrerenderBrowserTest& operator=(
+      const NavigationRequestPrerenderBrowserTest&) = delete;
+
+  void SetUpOnMainThread() override {
+    NavigationRequestBrowserTest::SetUpOnMainThread();
+
+    https_server_ = std::make_unique<net::EmbeddedTestServer>(
+        net::EmbeddedTestServer::TYPE_HTTPS);
+    https_server_->AddDefaultHandlers(GetTestDataFilePath());
+    https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+
+    ASSERT_TRUE(https_server()->Start());
+  }
+
+ protected:
+  net::EmbeddedTestServer* https_server() { return https_server_.get(); }
+
+  test::PrerenderTestHelper& prerender_helper() { return *prerender_helper_; }
+
+  WebContents* web_contents() { return shell()->web_contents(); }
+
+ private:
+  std::unique_ptr<net::EmbeddedTestServer> https_server_;
+  std::unique_ptr<test::PrerenderTestHelper> prerender_helper_;
+};
+
+IN_PROC_BROWSER_TEST_F(NavigationRequestPrerenderBrowserTest,
+                       CoopCoepCheckWithPrerender) {
+  GURL url(
+      https_server()->GetURL("a.test",
+                             "/set-header"
+                             "?cross-origin-opener-policy: same-origin"
+                             "&cross-origin-embedder-policy: require-corp"));
+
+  // Navigate to a document that sets COOP and COEP.
+  EXPECT_TRUE(NavigateToURL(shell(), url));
+  content::RenderFrameHostImpl* primary_main_frame =
+      static_cast<content::RenderFrameHostImpl*>(
+          shell()->web_contents()->GetPrimaryMainFrame());
+
+  EXPECT_EQ(network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep,
+            primary_main_frame->cross_origin_opener_policy().value);
+  EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp,
+            primary_main_frame->cross_origin_embedder_policy().value);
+
+  // Add a prerender.
+  int host_id = prerender_helper().AddPrerender(
+      https_server()->GetURL("a.test", "/title1.html?prerendering"));
+  content::RenderFrameHostImpl* prerender_main_frame =
+      static_cast<content::RenderFrameHostImpl*>(
+          prerender_helper().GetPrerenderedMainFrameHost(host_id));
+
+  // The prerender rfh's polices are none.
+  EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicyValue::kNone,
+            prerender_main_frame->cross_origin_embedder_policy().value);
+  EXPECT_EQ(network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone,
+            prerender_main_frame->cross_origin_opener_policy().value);
+
+  // Prerendering should not affect the primary rfh's polices.
+  EXPECT_EQ(network::mojom::CrossOriginOpenerPolicyValue::kSameOriginPlusCoep,
+            primary_main_frame->cross_origin_opener_policy().value);
+  EXPECT_EQ(network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp,
+            primary_main_frame->cross_origin_embedder_policy().value);
+}
+
 enum class TestMPArchType {
   kPrerender,
   kFencedFrame,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index ea62c4a9..e44c788 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
 
+#include <limits>
 #include <memory>
 #include <set>
 #include <utility>
@@ -1874,8 +1875,12 @@
   device_scale_factor_ = new_device_scale_factor;
   const display::Display display =
       display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
-  DCHECK_EQ(new_device_scale_factor, display.device_scale_factor());
-  current_cursor_.SetDisplayInfo(display);
+  // Sometimes GetDisplayNearestWindow returns the default monitor. We don't
+  // want to use that here.
+  if (display.is_valid()) {
+    DCHECK_EQ(new_device_scale_factor, display.device_scale_factor());
+    current_cursor_.SetDisplayInfo(display);
+  }
 }
 
 void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) {
diff --git a/content/renderer/browser_render_view_browsertest.cc b/content/renderer/browser_render_view_browsertest.cc
index 9e2a28e..1e32972 100644
--- a/content/renderer/browser_render_view_browsertest.cc
+++ b/content/renderer/browser_render_view_browsertest.cc
@@ -142,12 +142,14 @@
 };
 
 // https://crbug.com/788788
-#if BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)
+// TODO(crbug.com/1349962): Flaky on linux-tsan too.
+#if (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)) || \
+    (BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER))
 #define MAYBE_ConfirmCacheInformationPlumbed \
   DISABLED_ConfirmCacheInformationPlumbed
 #else
 #define MAYBE_ConfirmCacheInformationPlumbed ConfirmCacheInformationPlumbed
-#endif  // BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)
+#endif
 IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest,
                        MAYBE_ConfirmCacheInformationPlumbed) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
index 1b032ed..a229bad 100644
--- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
+++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -162,15 +162,6 @@
                      base::Unretained(this)));
 
   if (video_encode_accelerator_enabled_) {
-    {
-      // TODO(crbug.com/709631): This should be removed.
-      base::AutoLock lock(supported_profiles_lock_);
-      supported_vea_profiles_ =
-          media::GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
-              gpu_channel_host_->gpu_info()
-                  .video_encode_accelerator_supported_profiles);
-    }
-
     vea_provider_.set_disconnect_handler(base::BindOnce(
         &GpuVideoAcceleratorFactoriesImpl::OnEncoderSupportFailed,
         base::Unretained(this)));
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 26ec0c2e..ab9b43f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1562,8 +1562,6 @@
     render_frame = RenderFrameImpl::Create(
         agent_scheduling_group, routing_id, std::move(frame_receiver),
         std::move(browser_interface_broker), devtools_frame_token);
-    // Since `parent_web_frame` is remote we do not provide a parent_frame
-    // for initializing the BlameContext.
     render_frame->unique_name_helper_.set_propagated_name(
         replicated_state->unique_name);
     WebFrame* opener = nullptr;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index e3b66f1..987b3d9a 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -85,7 +85,6 @@
 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/public/platform/file_path_conversion.h"
 #include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
diff --git a/content/web_test/renderer/web_test_content_renderer_client.cc b/content/web_test/renderer/web_test_content_renderer_client.cc
index 0ff46ec..ae596f3 100644
--- a/content/web_test/renderer/web_test_content_renderer_client.cc
+++ b/content/web_test/renderer/web_test_content_renderer_client.cc
@@ -107,7 +107,7 @@
   // On these platforms, fonts are set up in the renderer process. Other
   // platforms set up fonts as part of WebTestBrowserMainRunner in the
   // browser process, via WebTestBrowserPlatformInitialize().
-  skia::ConfigureTestFont();
+  skia::InitializeSkFontMgrForTest();
 #elif BUILDFLAG(IS_WIN)
   // DirectWrite only has access to %WINDIR%\Fonts by default. For developer
   // side-loading, support kRegisterFontFiles to allow access to additional
diff --git a/docs/clion.md b/docs/clion.md
index 2c238473..5e47b32da 100644
--- a/docs/clion.md
+++ b/docs/clion.md
@@ -51,6 +51,8 @@
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/out/Default/gen)
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/protobuf/src)
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/googletest/src/googletest/include)
+       include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/googletest/src/googlemock/include)
+       include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/abseil-cpp)
        ```
     1. (Optional) Replace the `add_executable` files to include a single file;
        the file used is irrelevant. Doing this might improve CLion performance.
@@ -64,8 +66,11 @@
 
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/out/Default/gen)
+       include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/protobuf/src)
        include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/googletest/src/googletest/include)
-
+       include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/googletest/src/googlemock/include)
+       include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/abseil-cpp)
+   
        add_executable(chromium src/components/omnibox/browser/document_provider.cc)
        ```
 
diff --git a/docs/updater/functional_spec.md b/docs/updater/functional_spec.md
index d1a535f..c232461 100644
--- a/docs/updater/functional_spec.md
+++ b/docs/updater/functional_spec.md
@@ -349,6 +349,10 @@
 application's installer. The API for the application installer is platform-
 specific.
 
+Application installers are run with a 15-minute timeout. If the installer runs
+for longer than this, the updater assumes failure and continues operation.
+However, the updater does not kill the installer process.
+
 The macOS API is [defined here](installer_api_mac.md).
 
 TODO(crbug.com/1035895): Document Windows installer APIs
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index 5a805dc..c1c48c2 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -1732,12 +1732,6 @@
   return true;
 }
 
-size_t ExtensionWebRequestEventRouter::GetListenerCountForTesting(
-    content::BrowserContext* browser_context,
-    const std::string& event_name) {
-  return data_[browser_context].active_listeners[event_name].size();
-}
-
 ExtensionWebRequestEventRouter::EventListener*
 ExtensionWebRequestEventRouter::FindEventListener(const EventListener::ID& id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1896,6 +1890,12 @@
   data_.erase(browser_context);
 }
 
+size_t ExtensionWebRequestEventRouter::GetListenerCountForTesting(
+    content::BrowserContext* browser_context,
+    const std::string& event_name) {
+  return data_[browser_context].active_listeners[event_name].size();
+}
+
 bool ExtensionWebRequestEventRouter::HasAnyExtraHeadersListenerImpl(
     content::BrowserContext* browser_context) {
   auto iter = data_.find(browser_context);
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h
index b82b5db..ac3fa504 100644
--- a/extensions/browser/api/web_request/web_request_api.h
+++ b/extensions/browser/api/web_request/web_request_api.h
@@ -538,6 +538,10 @@
   // Called when a BrowserContext is being destroyed.
   void OnBrowserContextShutdown(content::BrowserContext* browser_context);
 
+  // Get the number of listeners - for testing only.
+  size_t GetListenerCountForTesting(content::BrowserContext* browser_context,
+                                    const std::string& event_name);
+
  private:
   friend class WebRequestAPI;
   friend class base::NoDestructor<ExtensionWebRequestEventRouter>;
@@ -765,10 +769,6 @@
   // Helper for |HasAnyExtraHeadersListener()|.
   bool HasAnyExtraHeadersListenerImpl(content::BrowserContext* browser_context);
 
-  // Get the number of listeners - for testing only.
-  size_t GetListenerCountForTesting(content::BrowserContext* browser_context,
-                                    const std::string& event_name);
-
   // A map of data associated with given BrowserContexts.
   DataMap data_;
 
diff --git a/extensions/browser/extensions_test.h b/extensions/browser/extensions_test.h
index b463e64..df1c021 100644
--- a/extensions/browser/extensions_test.h
+++ b/extensions/browser/extensions_test.h
@@ -72,6 +72,10 @@
         extension_system_factory_.GetForBrowserContext(browser_context_.get()));
   }
 
+  content::BrowserTaskEnvironment* task_environment() {
+    return task_environment_.get();
+  }
+
   // testing::Test overrides:
   void SetUp() override;
   void TearDown() override;
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc
index ea5fa4e..6e1dc99 100644
--- a/extensions/browser/sandboxed_unpacker.cc
+++ b/extensions/browser/sandboxed_unpacker.cc
@@ -158,6 +158,79 @@
 
 }  // namespace
 
+class SandboxedUnpacker::IOThreadState {
+ public:
+  IOThreadState() = default;
+  IOThreadState(const IOThreadState&) = delete;
+  IOThreadState& operator=(const IOThreadState&) = delete;
+  ~IOThreadState() = default;
+
+  void CleanUp() {
+    image_sanitizer_.reset();
+    json_file_sanitizer_.reset();
+    json_parser_.reset();
+  }
+
+  data_decoder::DataDecoder* GetDataDecoder() { return &data_decoder_; }
+
+  void CreateImangeSanitizer(
+      const extensions::Extension* extension,
+      const base::FilePath& extension_root,
+      scoped_refptr<ImageSanitizer::Client> client,
+      const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner) {
+    DCHECK(!image_sanitizer_);
+    std::set<base::FilePath> image_paths =
+        ExtensionsClient::Get()->GetBrowserImagePaths(extension);
+    image_sanitizer_ = ImageSanitizer::CreateAndStart(
+        client, extension_root, image_paths, unpacker_io_task_runner);
+  }
+
+  void CreateJsonFileSanitizer(
+      const std::set<base::FilePath>& message_catalog_paths,
+      JsonFileSanitizer::Callback callback,
+      const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner) {
+    json_file_sanitizer_ = JsonFileSanitizer::CreateAndStart(
+        GetDataDecoder(), message_catalog_paths, std::move(callback),
+        unpacker_io_task_runner);
+  }
+
+  data_decoder::mojom::JsonParser* GetJsonParserPtr(
+      SandboxedUnpacker* unpacker) {
+    if (!json_parser_) {
+      data_decoder_.GetService()->BindJsonParser(
+          json_parser_.BindNewPipeAndPassReceiver());
+      json_parser_.set_disconnect_handler(base::BindOnce(
+          &SandboxedUnpacker::ReportFailure, unpacker,
+          SandboxedUnpackerFailureReason::
+              UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
+          l10n_util::GetStringFUTF16(
+              IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+              u"UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL") +
+              u". " +
+              l10n_util::GetStringUTF16(
+                  IDS_EXTENSION_INSTALL_PROCESS_CRASHED)));
+    }
+
+    return json_parser_.get();
+  }
+
+ private:
+  // Controls our own lazily started, isolated instance of the Data Decoder
+  // service so that multiple decode operations related to this
+  // SandboxedUnpacker can share a single instance.
+  data_decoder::DataDecoder data_decoder_;
+
+  // The JSONParser remote from the data decoder service.
+  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
+
+  // The ImageSanitizer used to clean-up images.
+  std::unique_ptr<ImageSanitizer> image_sanitizer_;
+
+  // Used during the message catalog rewriting phase to sanitize the extension
+  // provided message catalogs.
+  std::unique_ptr<JsonFileSanitizer> json_file_sanitizer_;
+};
+
 SandboxedUnpackerClient::SandboxedUnpackerClient()
     : RefCountedDeleteOnSequence<SandboxedUnpackerClient>(
           content::GetUIThreadTaskRunner({})) {
@@ -200,7 +273,8 @@
       location_(location),
       creation_flags_(creation_flags),
       format_verifier_override_(g_verifier_format_override_for_test),
-      unpacker_io_task_runner_(unpacker_io_task_runner) {
+      unpacker_io_task_runner_(unpacker_io_task_runner),
+      io_thread_state_(std::make_unique<IOThreadState>()) {
   // Tracking for crbug.com/692069. The location must be valid. If it's invalid,
   // the utility process kills itself for a bad IPC.
   CHECK_GT(location, mojom::ManifestLocation::kInvalidLocation);
@@ -335,15 +409,7 @@
   // |temp_dir_| eventually.
   temp_dir_.Take();
 
-  // Make sure that members get deleted on the thread they were created.
-  if (image_sanitizer_) {
-    unpacker_io_task_runner_->DeleteSoon(FROM_HERE,
-                                         std::move(image_sanitizer_));
-  }
-  if (json_file_sanitizer_) {
-    unpacker_io_task_runner_->DeleteSoon(FROM_HERE,
-                                         std::move(json_file_sanitizer_));
-  }
+  unpacker_io_task_runner_->DeleteSoon(FROM_HERE, std::move(io_thread_state_));
 }
 
 void SandboxedUnpacker::Unzip(const base::FilePath& crx_path,
@@ -376,7 +442,7 @@
     Unpack(unzip_dir);
     return;
   }
-  data_decoder_.GzipUncompress(
+  GetDataDecoder()->GzipUncompress(
       compressed_verified_contents_,
       base::BindOnce(&SandboxedUnpacker::OnVerifiedContentsUncompressed, this,
                      unzip_dir));
@@ -552,15 +618,12 @@
 
   manifest_ = std::move(manifest);
 
-  DCHECK(!image_sanitizer_);
-  std::set<base::FilePath> image_paths =
-      ExtensionsClient::Get()->GetBrowserImagePaths(extension_.get());
-  image_sanitizer_ = ImageSanitizer::CreateAndStart(
-      this, extension_root_, image_paths, unpacker_io_task_runner_);
+  io_thread_state_->CreateImangeSanitizer(extension_.get(), extension_root_,
+                                          this, unpacker_io_task_runner_);
 }
 
 data_decoder::DataDecoder* SandboxedUnpacker::GetDataDecoder() {
-  return &data_decoder_;
+  return io_thread_state_->GetDataDecoder();
 }
 
 void SandboxedUnpacker::OnImageDecoded(const base::FilePath& path,
@@ -641,8 +704,8 @@
 void SandboxedUnpacker::SanitizeMessageCatalogs(
     const std::set<base::FilePath>& message_catalog_paths) {
   DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
-  json_file_sanitizer_ = JsonFileSanitizer::CreateAndStart(
-      &data_decoder_, message_catalog_paths,
+  io_thread_state_->CreateJsonFileSanitizer(
+      message_catalog_paths,
       base::BindOnce(&SandboxedUnpacker::MessageCatalogsSanitized, this),
       unpacker_io_task_runner_);
 }
@@ -763,20 +826,7 @@
 
 data_decoder::mojom::JsonParser* SandboxedUnpacker::GetJsonParserPtr() {
   DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence());
-  if (!json_parser_) {
-    data_decoder_.GetService()->BindJsonParser(
-        json_parser_.BindNewPipeAndPassReceiver());
-    json_parser_.set_disconnect_handler(base::BindOnce(
-        &SandboxedUnpacker::ReportFailure, this,
-        SandboxedUnpackerFailureReason::
-            UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
-        l10n_util::GetStringFUTF16(
-            IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
-            u"UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL") +
-            u". " +
-            l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)));
-  }
-  return json_parser_.get();
+  return io_thread_state_->GetJsonParserPtr(this);
 }
 
 void SandboxedUnpacker::ReportUnpackExtensionFailed(base::StringPiece error) {
@@ -1042,9 +1092,8 @@
     LOG(WARNING) << "Can not delete temp directory at "
                  << temp_dir_.GetPath().value();
   }
-  image_sanitizer_.reset();
-  json_file_sanitizer_.reset();
-  json_parser_.reset();
+
+  io_thread_state_->CleanUp();
 }
 
 void SandboxedUnpacker::ParseJsonFile(
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h
index c774dd2..d5e22a7 100644
--- a/extensions/browser/sandboxed_unpacker.h
+++ b/extensions/browser/sandboxed_unpacker.h
@@ -160,6 +160,7 @@
 
  private:
   friend class SandboxedUnpackerTest;
+  class IOThreadState;
 
   ~SandboxedUnpacker() override;
 
@@ -315,20 +316,8 @@
   // The decoded install icon.
   SkBitmap install_icon_;
 
-  // Controls our own lazily started, isolated instance of the Data Decoder
-  // service so that multiple decode operations related to this
-  // SandboxedUnpacker can share a single instance.
-  data_decoder::DataDecoder data_decoder_;
-
-  // The JSONParser remote from the data decoder service.
-  mojo::Remote<data_decoder::mojom::JsonParser> json_parser_;
-
-  // The ImageSanitizer used to clean-up images.
-  std::unique_ptr<ImageSanitizer> image_sanitizer_;
-
-  // Used during the message catalog rewriting phase to sanitize the extension
-  // provided message catalogs.
-  std::unique_ptr<JsonFileSanitizer> json_file_sanitizer_;
+  // TODO(crbug.com/1346172): Consider to wrap it in base::SequenceBound
+  std::unique_ptr<IOThreadState> io_thread_state_;
 };
 
 }  // namespace extensions
diff --git a/extensions/browser/sandboxed_unpacker_unittest.cc b/extensions/browser/sandboxed_unpacker_unittest.cc
index b3737f2..2d9a4bd 100644
--- a/extensions/browser/sandboxed_unpacker_unittest.cc
+++ b/extensions/browser/sandboxed_unpacker_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/strings/pattern.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "components/crx_file/id_util.h"
@@ -82,12 +83,9 @@
 
 class MockSandboxedUnpackerClient : public SandboxedUnpackerClient {
  public:
-  void WaitForUnpack() {
-    scoped_refptr<content::MessageLoopRunner> runner =
-        new content::MessageLoopRunner;
-    quit_closure_ = runner->QuitClosure();
-    runner->Run();
-  }
+  explicit MockSandboxedUnpackerClient(
+      scoped_refptr<base::SequencedTaskRunner> callback_runner)
+      : callback_runner_(callback_runner) {}
 
   base::FilePath temp_dir() const { return temp_dir_; }
   std::u16string unpack_error_message() const {
@@ -117,10 +115,16 @@
     should_compute_hashes_ = should_compute_hashes;
   }
 
+  void SetQuitClosure(base::OnceClosure quit_closure) {
+    quit_closure_ = std::move(quit_closure);
+  }
+
  private:
   ~MockSandboxedUnpackerClient() override {
     if (deleted_tracker_)
       *deleted_tracker_ = true;
+    if (quit_closure_)
+      std::move(quit_closure_).Run();
   }
 
   void ShouldComputeHashesForOffWebstoreExtension(
@@ -137,14 +141,15 @@
                        declarative_net_request::RulesetInstallPrefs
                            ruleset_install_prefs) override {
     temp_dir_ = temp_dir;
-    std::move(quit_closure_).Run();
+    callback_runner_->PostTask(FROM_HERE, std::move(quit_closure_));
   }
 
   void OnUnpackFailure(const CrxInstallError& error) override {
     error_ = error;
-    std::move(quit_closure_).Run();
+    callback_runner_->PostTask(FROM_HERE, std::move(quit_closure_));
   }
 
+  scoped_refptr<base::SequencedTaskRunner> callback_runner_;
   absl::optional<CrxInstallError> error_;
   base::OnceClosure quit_closure_;
   base::FilePath temp_dir_;
@@ -155,15 +160,21 @@
 class SandboxedUnpackerTest : public ExtensionsTest {
  public:
   SandboxedUnpackerTest()
-      : ExtensionsTest(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
+      : ExtensionsTest(content::BrowserTaskEnvironment::IO_MAINLOOP),
+        unpacker_thread_("Unpacker Thread") {}
 
   void SetUp() override {
     ExtensionsTest::SetUp();
+
+    unpacker_thread_.Start();
+    unpacker_task_runner_ = unpacker_thread_.task_runner();
+
     ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir());
     in_process_utility_thread_helper_ =
         std::make_unique<content::InProcessUtilityThreadHelper>();
     // It will delete itself.
-    client_ = new MockSandboxedUnpackerClient;
+    client_ = new MockSandboxedUnpackerClient(
+        task_environment()->GetMainThreadTaskRunner());
 
     InitSandboxedUnpacker();
 
@@ -175,10 +186,9 @@
   }
 
   void InitSandboxedUnpacker() {
-    sandboxed_unpacker_ =
-        new SandboxedUnpacker(mojom::ManifestLocation::kInternal,
-                              Extension::NO_FLAGS, extensions_dir_.GetPath(),
-                              base::ThreadTaskRunnerHandle::Get(), client_);
+    sandboxed_unpacker_ = new SandboxedUnpacker(
+        mojom::ManifestLocation::kInternal, Extension::NO_FLAGS,
+        extensions_dir_.GetPath(), unpacker_task_runner_, client_);
   }
 
   void TearDown() override {
@@ -189,6 +199,8 @@
     base::RunLoop().RunUntilIdle();
     ExtensionsTest::TearDown();
     in_process_utility_thread_helper_.reset();
+
+    unpacker_thread_.Stop();
   }
 
   base::FilePath GetCrxFullPath(const std::string& crx_name) {
@@ -204,10 +216,15 @@
     base::FilePath crx_path = GetCrxFullPath(crx_name);
     extensions::CRXFileInfo crx_info(crx_path, GetTestVerifierFormat());
     crx_info.expected_hash = package_hash;
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
+
+    base::RunLoop run_loop;
+    client_->SetQuitClosure(run_loop.QuitClosure());
+
+    unpacker_task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&SandboxedUnpacker::StartWithCrx,
                                   sandboxed_unpacker_, crx_info));
-    client_->WaitForUnpack();
+    // Wait for unpack
+    run_loop.Run();
   }
 
   void SetupUnpackerWithDirectory(const std::string& crx_name) {
@@ -219,11 +236,17 @@
     std::string fake_id = crx_file::id_util::GenerateId(crx_name);
     std::string fake_public_key;
     base::Base64Encode(std::string(2048, 'k'), &fake_public_key);
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
+
+    base::RunLoop run_loop;
+    client_->SetQuitClosure(run_loop.QuitClosure());
+
+    unpacker_task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&SandboxedUnpacker::StartWithDirectory,
                                   sandboxed_unpacker_, fake_id, fake_public_key,
                                   temp_dir.Take()));
-    client_->WaitForUnpack();
+
+    // Wait for unpack
+    run_loop.Run();
   }
 
   bool InstallSucceeded() const { return !client_->temp_dir().empty(); }
@@ -256,9 +279,17 @@
     client_->set_deleted_tracker(&client_deleted);
     SetupUnpacker(package_name, "");
     EXPECT_EQ(GetInstallErrorMessage().empty(), expect_success);
+
+    base::RunLoop run_loop;
+    client_->SetQuitClosure(run_loop.QuitClosure());
+
     // Remove our reference to |sandboxed_unpacker_|, it should get deleted
     // since/ it's the last reference.
     sandboxed_unpacker_ = nullptr;
+
+    // Wait for |client_| dtor.
+    run_loop.Run();
+
     // The SandboxedUnpacker should have been deleted and deleted the client.
     EXPECT_TRUE(client_deleted);
   }
@@ -287,6 +318,13 @@
       in_process_utility_thread_helper_;
 
   data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
+
+ private:
+  // The thread where the sandboxed unpacker runs. This provides test coverage
+  // in an environment similar to what we use in production.
+  base::Thread unpacker_thread_;
+
+  scoped_refptr<base::SequencedTaskRunner> unpacker_task_runner_;
 };
 
 TEST_F(SandboxedUnpackerTest, EmptyDefaultLocale) {
@@ -424,13 +462,7 @@
   EXPECT_EQ(CrxInstallErrorType::NONE, GetInstallErrorType());
 }
 
-// TODO(crbug.com/1348091): Re-enable this test
-#if BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)
-#define MAYBE_FailHashCheck DISABLED_FailHashCheck
-#else
-#define MAYBE_FailHashCheck FailHashCheck
-#endif
-TEST_F(SandboxedUnpackerTest, MAYBE_FailHashCheck) {
+TEST_F(SandboxedUnpackerTest, FailHashCheck) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       extensions::switches::kEnableCrxHashCheck);
   SetupUnpacker("good_l10n.crx", std::string(64, '0'));
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h
index 13a35af..2e78b8a5 100644
--- a/gpu/config/gpu_info.h
+++ b/gpu/config/gpu_info.h
@@ -438,6 +438,8 @@
   VideoDecodeAcceleratorSupportedProfiles
       video_decode_accelerator_supported_profiles;
 
+  // DO NOT use for anything but diagnostics/metrics like chrome://gpu,
+  // it's not populated at start up and can be unreliable for a while.
   VideoEncodeAcceleratorSupportedProfiles
       video_encode_accelerator_supported_profiles;
   bool jpeg_decode_accelerator_supported;
diff --git a/infra/config/generated/builders/ci/ToTiOS/properties.json b/infra/config/generated/builders/ci/ToTiOS/properties.json
index 13d9a2f..23f5f28 100644
--- a/infra/config/generated/builders/ci/ToTiOS/properties.json
+++ b/infra/config/generated/builders/ci/ToTiOS/properties.json
@@ -12,5 +12,5 @@
   "sheriff_rotations": [
     "chromium.clang"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ToTiOSDevice/properties.json b/infra/config/generated/builders/ci/ToTiOSDevice/properties.json
index 13d9a2f..23f5f28 100644
--- a/infra/config/generated/builders/ci/ToTiOSDevice/properties.json
+++ b/infra/config/generated/builders/ci/ToTiOSDevice/properties.json
@@ -12,5 +12,5 @@
   "sheriff_rotations": [
     "chromium.clang"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/android-pie-x86-fyi-rel-reviver/properties.json b/infra/config/generated/builders/ci/android-pie-x86-fyi-rel-reviver/properties.json
new file mode 100644
index 0000000..127ad1d
--- /dev/null
+++ b/infra/config/generated/builders/ci/android-pie-x86-fyi-rel-reviver/properties.json
@@ -0,0 +1,68 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "android-pie-x86-fyi-rel-reviver",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-android-archive",
+              "builder_group": "chromium.android.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_android_config": {
+                "config": "x86_builder"
+              },
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "android",
+                "target_bits": 32,
+                "target_platform": "android"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "android",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "android-pie-x86-fyi-rel-reviver",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "android-pie-x86-fyi-rel-reviver",
+          "group": "tryserver.chromium.android"
+        }
+      ]
+    }
+  },
+  "$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.android.fyi",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-asan/properties.json b/infra/config/generated/builders/ci/ios-asan/properties.json
index f854dc4..e1812840 100644
--- a/infra/config/generated/builders/ci/ios-asan/properties.json
+++ b/infra/config/generated/builders/ci/ios-asan/properties.json
@@ -72,5 +72,5 @@
   "sheriff_rotations": [
     "ios"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/ios-device \050reclient shadow\051/properties.json" "b/infra/config/generated/builders/ci/ios-device \050reclient shadow\051/properties.json"
index 4cfe3306..3a2973b1 100644
--- "a/infra/config/generated/builders/ci/ios-device \050reclient shadow\051/properties.json"
+++ "b/infra/config/generated/builders/ci/ios-device \050reclient shadow\051/properties.json"
@@ -52,5 +52,5 @@
   },
   "builder_group": "chromium.mac",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-device/properties.json b/infra/config/generated/builders/ci/ios-device/properties.json
index d76f732..fcb43a8 100644
--- a/infra/config/generated/builders/ci/ios-device/properties.json
+++ b/infra/config/generated/builders/ci/ios-device/properties.json
@@ -63,5 +63,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
index a968ffb..84de154 100644
--- a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
+++ b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
@@ -58,5 +58,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
index f7f5427..b95d9ef 100644
--- a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
@@ -58,5 +58,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
index 409d530..3d9ac96 100644
--- a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
@@ -58,5 +58,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-reclient/properties.json b/infra/config/generated/builders/ci/ios-reclient/properties.json
index 3a80cd1..a10a379 100644
--- a/infra/config/generated/builders/ci/ios-reclient/properties.json
+++ b/infra/config/generated/builders/ci/ios-reclient/properties.json
@@ -17,5 +17,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
index ffb8a12..94ed5b8 100644
--- a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
@@ -21,5 +21,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/ios-simulator-cronet \050reclient shadow\051/properties.json" "b/infra/config/generated/builders/ci/ios-simulator-cronet \050reclient shadow\051/properties.json"
index 8ce98a6..a1f0c8c4 100644
--- "a/infra/config/generated/builders/ci/ios-simulator-cronet \050reclient shadow\051/properties.json"
+++ "b/infra/config/generated/builders/ci/ios-simulator-cronet \050reclient shadow\051/properties.json"
@@ -53,5 +53,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
index 01e2183..a7f22e2e 100644
--- a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
index d68327d..b012a427 100644
--- a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
@@ -66,5 +66,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
index c18caf9e..f374d105 100644
--- a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
index ed29b66..70c69af 100644
--- a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
@@ -63,5 +63,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator/properties.json b/infra/config/generated/builders/ci/ios-simulator/properties.json
index 4878542..d8d195f 100644
--- a/infra/config/generated/builders/ci/ios-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator/properties.json
@@ -74,5 +74,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios15-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios15-beta-simulator/properties.json
index c18caf9e..f374d105 100644
--- a/infra/config/generated/builders/ci/ios15-beta-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios15-beta-simulator/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios15-sdk-device/properties.json b/infra/config/generated/builders/ci/ios15-sdk-device/properties.json
index 3e96b353..f374d105 100644
--- a/infra/config/generated/builders/ci/ios15-sdk-device/properties.json
+++ b/infra/config/generated/builders/ci/ios15-sdk-device/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13f17a"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios15-sdk-simulator/properties.json b/infra/config/generated/builders/ci/ios15-sdk-simulator/properties.json
index 3e96b353..f374d105 100644
--- a/infra/config/generated/builders/ci/ios15-sdk-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios15-sdk-simulator/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13f17a"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
index 40047b4..4520d9b3 100644
--- a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-pie-x86-fyi-rel-reviver/properties.json b/infra/config/generated/builders/try/android-pie-x86-fyi-rel-reviver/properties.json
new file mode 100644
index 0000000..e17d164
--- /dev/null
+++ b/infra/config/generated/builders/try/android-pie-x86-fyi-rel-reviver/properties.json
@@ -0,0 +1,64 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "android-pie-x86-fyi-rel-reviver",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-android-archive",
+              "builder_group": "chromium.android.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_android_config": {
+                "config": "x86_builder"
+              },
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "android",
+                "target_bits": 32,
+                "target_platform": "android"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "android",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "android-pie-x86-fyi-rel-reviver",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/goma": {
+    "enable_ats": true,
+    "jobs": 150,
+    "rpc_extra_params": "?prod",
+    "server_host": "goma.chromium.org",
+    "use_luci_auth": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.android",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-asan/properties.json b/infra/config/generated/builders/try/ios-asan/properties.json
index 8235a51..7fdc3b88 100644
--- a/infra/config/generated/builders/try/ios-asan/properties.json
+++ b/infra/config/generated/builders/try/ios-asan/properties.json
@@ -58,5 +58,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-catalyst/properties.json b/infra/config/generated/builders/try/ios-catalyst/properties.json
index 3b7d80f..dd387d9b 100644
--- a/infra/config/generated/builders/try/ios-catalyst/properties.json
+++ b/infra/config/generated/builders/try/ios-catalyst/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-device/properties.json b/infra/config/generated/builders/try/ios-device/properties.json
index 964b170..9947b9135 100644
--- a/infra/config/generated/builders/try/ios-device/properties.json
+++ b/infra/config/generated/builders/try/ios-device/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
index 2e92ad0..d227fcd4 100644
--- a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
+++ b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
index 11ac1f17..fdecef5 100644
--- a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator/properties.json b/infra/config/generated/builders/try/ios-m1-simulator/properties.json
index eacb3c6..419f8a6 100644
--- a/infra/config/generated/builders/try/ios-m1-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios-m1-simulator/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
index 9491a02..866f073 100644
--- a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
@@ -56,5 +56,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
index 0f09cc6..3b4c631 100644
--- a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
@@ -67,5 +67,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
index 1ee7f91..d7e33ce 100644
--- a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
@@ -56,5 +56,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
index b9041d6..af93700 100644
--- a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
index 452ec9f..a8e95c9 100644
--- a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-rts/properties.json b/infra/config/generated/builders/try/ios-simulator-rts/properties.json
index dba3968..002fe08 100644
--- a/infra/config/generated/builders/try/ios-simulator-rts/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-rts/properties.json
@@ -70,5 +70,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator/properties.json b/infra/config/generated/builders/try/ios-simulator/properties.json
index 5137f096..2bf890a0 100644
--- a/infra/config/generated/builders/try/ios-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator/properties.json
@@ -67,5 +67,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios15-beta-simulator/properties.json b/infra/config/generated/builders/try/ios15-beta-simulator/properties.json
index b9041d6..af93700 100644
--- a/infra/config/generated/builders/try/ios15-beta-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios15-beta-simulator/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios15-sdk-simulator/properties.json b/infra/config/generated/builders/try/ios15-sdk-simulator/properties.json
index 8863398..af93700 100644
--- a/infra/config/generated/builders/try/ios15-sdk-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios15-sdk-simulator/properties.json
@@ -13,5 +13,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13f17a"
+  "xcode_build_version": "14a5270f"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
index d39f3de..950e3c6 100644
--- a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "13c100"
+  "xcode_build_version": "14a5270f"
 }
\ 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 3a4f88623..8fa70ea 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -808,6 +808,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/android-pie-x86-fyi-rel-reviver"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/android-pie-x86-rel"
         includable_only: true
       }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 8cc18cf..d27bc27 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -4031,12 +4031,12 @@
         '  },'
         '  "builder_group": "chromium.fyi",'
         '  "recipe": "reclient_goma_comparison",'
-        '  "xcode_build_version": "13c100"'
+        '  "xcode_build_version": "14a5270f"'
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -4114,12 +4114,12 @@
         '  },'
         '  "builder_group": "chromium.fyi",'
         '  "recipe": "reclient_goma_comparison",'
-        '  "xcode_build_version": "13c100"'
+        '  "xcode_build_version": "14a5270f"'
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -10030,12 +10030,12 @@
         '  },'
         '  "builder_group": "chromium.fuzz",'
         '  "recipe": "chromium_libfuzzer",'
-        '  "xcode_build_version": "13c100"'
+        '  "xcode_build_version": "14a5270f"'
         '}'
       execution_timeout_secs: 14400
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -19675,8 +19675,8 @@
         '}'
       execution_timeout_secs: 50400
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -19760,8 +19760,8 @@
         '}'
       execution_timeout_secs: 50400
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -26975,6 +26975,86 @@
       }
     }
     builders {
+      name: "android-pie-x86-fyi-rel-reviver"
+      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/android-pie-x86-fyi-rel-reviver/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.android.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      execution_timeout_secs: 10800
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      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/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "android-pie-x86-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -31732,12 +31812,12 @@
         '  "sheriff_rotations": ['
         '    "angle"'
         '  ],'
-        '  "xcode_build_version": "13c100"'
+        '  "xcode_build_version": "14a5270f"'
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -31976,8 +32056,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32146,8 +32226,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32228,8 +32308,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32308,8 +32388,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32389,8 +32469,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32470,8 +32550,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32552,8 +32632,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32638,8 +32718,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32720,8 +32800,8 @@
         '}'
       execution_timeout_secs: 72000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32800,8 +32880,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32882,8 +32962,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -32967,8 +33047,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33047,8 +33127,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33132,8 +33212,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33293,8 +33373,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33374,8 +33454,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13f17a"
-        path: "xcode_ios_13f17a.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33455,8 +33535,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13f17a"
-        path: "xcode_ios_13f17a.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -33536,8 +33616,8 @@
         '}'
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -53994,6 +54074,96 @@
       }
     }
     builders {
+      name: "android-pie-x86-fyi-rel-reviver"
+      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/android-pie-x86-fyi-rel-reviver/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.android",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      caches {
+        name: "win_toolchain"
+        path: "win_toolchain"
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      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/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "android-pie-x86-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -64545,8 +64715,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -64637,8 +64807,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -64815,8 +64985,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -64907,8 +65077,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -64999,8 +65169,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65091,8 +65261,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65183,8 +65353,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65279,8 +65449,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65371,8 +65541,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65463,8 +65633,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65555,8 +65725,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65647,8 +65817,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65739,8 +65909,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65831,8 +66001,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -65923,8 +66093,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13f17a"
-        path: "xcode_ios_13f17a.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -66015,8 +66185,8 @@
         path: "win_toolchain"
       }
       caches {
-        name: "xcode_ios_13c100"
-        path: "xcode_ios_13c100.app"
+        name: "xcode_ios_14a5270f"
+        path: "xcode_ios_14a5270f.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 7724d5f..d014f0c9 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -4200,6 +4200,11 @@
     short_name: "x86"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/android-pie-x86-fyi-rel-reviver"
+    category: "builder_tester|x86"
+    short_name: "P"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/android-cronet-asan-x86-rel"
     category: "cronet|asan"
   }
@@ -16098,6 +16103,9 @@
     name: "buildbucket/luci.chromium.try/android-pie-arm64-wpt-rel-non-cq"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/android-pie-x86-fyi-rel-reviver"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/android-pie-x86-rel"
   }
   builders {
@@ -17228,6 +17236,9 @@
     name: "buildbucket/luci.chromium.try/android-pie-arm64-wpt-rel-non-cq"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/android-pie-x86-fyi-rel-reviver"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/android-pie-x86-rel"
   }
   builders {
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star
index 06470c87..8e78c72 100644
--- a/infra/config/lib/builders.star
+++ b/infra/config/lib/builders.star
@@ -185,6 +185,8 @@
     x13main = xcode_enum("13c100"),
     # A newer Xcode 13 version used on beta bots.
     x13betabots = xcode_enum("13f17a"),
+    # Xcode14 beta 3 will be used to build Main iOS
+    x14main = xcode_enum("14a5270f"),
     # A newer Xcode 14 version used on beta bots.
     x14betabots = xcode_enum("14a5284g"),
     # in use by ios-webkit-tot
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star
index 7a88cef..07d91601 100644
--- a/infra/config/subprojects/chromium/ci/chromium.android.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.android.fyi.star
@@ -150,6 +150,40 @@
     triggered_by = [],
 )
 
+ci.builder(
+    name = "android-pie-x86-fyi-rel-reviver",
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "android",
+                "enable_reclient",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "android",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 32,
+            target_platform = builder_config.target_platform.ANDROID,
+        ),
+        android_config = builder_config.android_config(
+            config = "x86_builder",
+        ),
+        build_gs_bucket = "chromium-android-archive",
+    ),
+    console_view_entry = consoles.console_view_entry(
+        category = "builder_tester|x86",
+        short_name = "P",
+    ),
+    # Set to an empty list to avoid chromium-gitiles-trigger triggering new
+    # builds. Also we don't set any `schedule` since this builder is for
+    # reference only and should not run any new builds.
+    triggered_by = [],
+)
+
 # TODO(crbug.com/1137474): This and android-12-x64-fyi-rel
 # are being kept around so that build links in the related
 # bugs are accessible
diff --git a/infra/config/subprojects/chromium/ci/chromium.angle.star b/infra/config/subprojects/chromium/ci/chromium.angle.star
index 0c37863..72c4472 100644
--- a/infra/config/subprojects/chromium/ci/chromium.angle.star
+++ b/infra/config/subprojects/chromium/ci/chromium.angle.star
@@ -147,7 +147,7 @@
     ),
     goma_backend = goma.backend.RBE_PROD,
     reclient_instance = None,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 ci.thin_tester(
diff --git a/infra/config/subprojects/chromium/ci/chromium.clang.star b/infra/config/subprojects/chromium/ci/chromium.clang.star
index c56d11d..e5c0a127 100644
--- a/infra/config/subprojects/chromium/ci/chromium.clang.star
+++ b/infra/config/subprojects/chromium/ci/chromium.clang.star
@@ -399,7 +399,7 @@
     cores = None,
     os = os.MAC_12,
     ssd = True,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 ci.builder(
@@ -412,7 +412,7 @@
     cores = None,
     os = os.MAC_12,
     ssd = True,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 clang_mac_builder(
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
index b147790..2d3a696 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -299,7 +299,7 @@
     executable = "recipe:chromium_libfuzzer",
     execution_timeout = 4 * time.hour,
     os = os.MAC_12,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
     goma_backend = goma.backend.RBE_PROD,
     reclient_instance = None,
 )
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 279a23a3..347b7cd 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -77,7 +77,7 @@
     kwargs.setdefault("cores", None)
     if kwargs.get("builderless", False):
         kwargs.setdefault("os", os.MAC_DEFAULT)
-    kwargs.setdefault("xcode", xcode.x13main)
+    kwargs.setdefault("xcode", xcode.x14main)
     return ci.builder(name = name, **kwargs)
 
 def fyi_mac_builder(*, name, **kwargs):
@@ -1001,7 +1001,7 @@
     reclient_jobs = 250,
     os = os.MAC_DEFAULT,
     cores = None,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 ci.builder(
@@ -1132,7 +1132,7 @@
     os = os.MAC_DEFAULT,
     cores = None,
     ssd = True,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 # Build Perf builders use CQ reclient instance and high reclient jobs/cores and
@@ -1635,7 +1635,7 @@
     use_clang_coverage = True,
     coverage_exclude_sources = "ios_test_files_and_test_utils",
     coverage_test_types = ["overall", "unit"],
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 fyi_coverage_builder(
@@ -1871,7 +1871,6 @@
         ),
     ],
     os = os.MAC_12,
-    xcode = xcode.x13betabots,
 )
 
 fyi_ios_builder(
@@ -1883,7 +1882,6 @@
         ),
     ],
     os = os.MAC_12,
-    xcode = xcode.x13betabots,
 )
 
 fyi_ios_builder(
diff --git a/infra/config/subprojects/chromium/ci/chromium.mac.star b/infra/config/subprojects/chromium/ci/chromium.mac.star
index b8ad4ec..7accde8 100644
--- a/infra/config/subprojects/chromium/ci/chromium.mac.star
+++ b/infra/config/subprojects/chromium/ci/chromium.mac.star
@@ -49,7 +49,7 @@
 
 def ios_builder(*, name, **kwargs):
     kwargs.setdefault("sheriff_rotations", sheriff_rotations.IOS)
-    kwargs.setdefault("xcode", xcode.x13main)
+    kwargs.setdefault("xcode", xcode.x14main)
     return ci.builder(name = name, **kwargs)
 
 ci.builder(
@@ -415,6 +415,7 @@
     # We don't have necessary capacity to run this configuration in CQ, but it
     # is part of the main waterfall
     name = "ios-catalyst",
+    xcode = xcode.x13main,
     builder_spec = builder_config.builder_spec(
         gclient_config = builder_config.gclient_config(
             config = "ios",
@@ -608,5 +609,5 @@
     ],
     # We don't have necessary capacity to run this configuration in CQ, but it
     # is part of the main waterfall
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
diff --git a/infra/config/subprojects/chromium/ci/chromium.memory.star b/infra/config/subprojects/chromium/ci/chromium.memory.star
index 60b5230..9258951 100644
--- a/infra/config/subprojects/chromium/ci/chromium.memory.star
+++ b/infra/config/subprojects/chromium/ci/chromium.memory.star
@@ -647,7 +647,7 @@
     sheriff_rotations = args.ignore_default(sheriff_rotations.IOS),
     cores = None,
     os = os.MAC_12,
-    xcode = xcode.x13main,
+    xcode = xcode.x14main,
 )
 
 # TODO(crbug.com/1340327): Remove after experiment is over.
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
index 0d77cfa..859f6638 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -410,6 +410,14 @@
     goma_jobs = goma.jobs.J150,
 )
 
+try_.builder(
+    name = "android-pie-x86-fyi-rel-reviver",
+    mirrors = [
+        "ci/android-pie-x86-fyi-rel-reviver",
+    ],
+    goma_jobs = goma.jobs.J150,
+)
+
 # TODO(crbug/1182468) Remove when coverage is enabled on CQ.
 try_.builder(
     name = "android-pie-arm64-coverage-rel",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
index 26e2ab2..e9f682c0 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -27,7 +27,7 @@
     kwargs.setdefault("builderless", False)
     kwargs.setdefault("os", os.MAC_DEFAULT)
     kwargs.setdefault("ssd", None)
-    kwargs.setdefault("xcode", xcode.x13main)
+    kwargs.setdefault("xcode", xcode.x14main)
     return try_.builder(name = name, **kwargs)
 
 consoles.list_view(
@@ -375,7 +375,6 @@
     mirrors = [
         "ci/ios-simulator-noncq",
     ],
-    xcode = xcode.x13main,
     tryjob = try_.job(
         location_regexp = [
             ".+/[+]/third_party/crashpad/crashpad/.+",
@@ -389,7 +388,6 @@
 
 ios_builder(
     name = "ios15-sdk-simulator",
-    xcode = xcode.x13betabots,
     os = os.MAC_12,
 )
 
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
index 4214d2a0..846a330 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
@@ -26,7 +26,6 @@
 #include "ios/chrome/browser/variations/ios_chrome_variations_service_client.h"
 #include "ios/chrome/browser/variations/ios_ui_string_overrider_factory.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
-#include "ios/chrome/common/channel_info.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -89,7 +88,7 @@
     base::PathService::Get(ios::DIR_USER_DATA, &user_data_dir);
     metrics_state_manager_ = metrics::MetricsStateManager::Create(
         local_state_, enabled_state_provider_.get(), std::wstring(),
-        user_data_dir, metrics::StartupVisibility::kUnknown, GetChannel());
+        user_data_dir, metrics::StartupVisibility::kUnknown);
   }
   return metrics_state_manager_.get();
 }
diff --git a/ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.mm b/ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.mm
index 95efe8d6..ba70561 100644
--- a/ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.mm
+++ b/ios/chrome/browser/segmentation_platform/segmentation_platform_service_factory.mm
@@ -75,7 +75,9 @@
     return nullptr;
   }
 
-  DCHECK(!context->IsOffTheRecord());
+  if (!context || context->IsOffTheRecord()) {
+    return nullptr;
+  }
 
   ChromeBrowserState* chrome_browser_state =
       ChromeBrowserState::FromBrowserState(context);
@@ -84,6 +86,11 @@
   auto* optimization_guide =
       OptimizationGuideServiceFactory::GetForBrowserState(chrome_browser_state);
 
+  auto* protodb_provider = chrome_browser_state->GetProtoDatabaseProvider();
+  if (!protodb_provider) {
+    return nullptr;
+  }
+
   auto params = std::make_unique<SegmentationPlatformServiceImpl::InitParams>();
 
   params->history_service = ios::HistoryServiceFactory::GetForBrowserState(
@@ -92,7 +99,7 @@
       {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
   params->storage_dir =
       profile_path.Append(kSegmentationPlatformStorageDirName);
-  params->db_provider = chrome_browser_state->GetProtoDatabaseProvider();
+  params->db_provider = protodb_provider;
   params->clock = base::DefaultClock::GetInstance();
 
   params->model_provider = std::make_unique<ModelProviderFactoryImpl>(
diff --git a/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h b/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
index 6f92eff..4850b13 100644
--- a/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
+++ b/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.h
@@ -46,7 +46,7 @@
   void RegisterMessages() override;
 
   // LogReceiver implementation.
-  void LogEntry(const base::Value& entry) override;
+  void LogEntry(const base::Value::Dict& entry) override;
 
   void StartSubscription();
   void EndSubscription();
diff --git a/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.mm b/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.mm
index 6c21770..0481207 100644
--- a/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.mm
+++ b/ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/internals_ui_handler.mm
@@ -104,8 +104,8 @@
     log_router->UnregisterReceiver(this);
 }
 
-void InternalsUIHandler::LogEntry(const base::Value& entry) {
-  if (!registered_with_log_router_ || entry.is_none())
+void InternalsUIHandler::LogEntry(const base::Value::Dict& entry) {
+  if (!registered_with_log_router_)
     return;
 
   base::Value log_event("add-structured-log");
diff --git a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc
index 0cb92d1a..406f397e 100644
--- a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc
+++ b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc
@@ -90,7 +90,7 @@
   // empty in incognito mode. Alternatively, we could force about:signin to
   // open in non-incognito mode always (like about:settings for ex.).
   about_signin_internals->AddSigninObserver(this);
-  const base::Value status = about_signin_internals->GetSigninStatus();
+  const base::Value::Dict status = about_signin_internals->GetSigninStatus();
   base::ValueView return_args[] = {callback, success, status};
   web_ui()->CallJavascriptFunction("cr.webUIResponse", return_args);
   signin::IdentityManager* identity_manager =
@@ -104,17 +104,16 @@
   }
 }
 
-void SignInInternalsHandlerIOS::OnSigninStateChanged(const base::Value* info) {
-  DCHECK(info);
+void SignInInternalsHandlerIOS::OnSigninStateChanged(
+    const base::Value::Dict& info) {
   base::Value event_name("signin-info-changed");
-  base::ValueView args[] = {event_name, *info};
+  base::ValueView args[] = {event_name, info};
   web_ui()->CallJavascriptFunction("cr.webUIListenerCallback", args);
 }
 
 void SignInInternalsHandlerIOS::OnCookieAccountsFetched(
-    const base::Value* info) {
-  DCHECK(info);
+    const base::Value::Dict& info) {
   base::Value event_name("update-cookie-accounts");
-  base::ValueView args[] = {event_name, *info};
+  base::ValueView args[] = {event_name, info};
   web_ui()->CallJavascriptFunction("cr.webUIListenerCallback", args);
 }
diff --git a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.h b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.h
index d7c531a..c2ab245 100644
--- a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.h
+++ b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.h
@@ -37,10 +37,10 @@
   void HandleGetSignInInfo(const base::Value::List& args);
 
   // AboutSigninInternals::Observer::OnSigninStateChanged implementation.
-  void OnSigninStateChanged(const base::Value* info) override;
+  void OnSigninStateChanged(const base::Value::Dict& info) override;
 
   // Notification that the cookie accounts are ready to be displayed.
-  void OnCookieAccountsFetched(const base::Value* info) override;
+  void OnCookieAccountsFetched(const base::Value::Dict& info) override;
 };
 
 #endif  // IOS_CHROME_BROWSER_UI_WEBUI_SIGNIN_INTERNALS_UI_IOS_H_
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn
index e2d9961b..7d45fe6f 100644
--- a/media/base/android/BUILD.gn
+++ b/media/base/android/BUILD.gn
@@ -179,6 +179,7 @@
     sources = [
       "java/src/org/chromium/media/AudioDeviceListener.java",
       "java/src/org/chromium/media/AudioDeviceSelector.java",
+      "java/src/org/chromium/media/AudioDeviceSelectorPostS.java",
       "java/src/org/chromium/media/AudioDeviceSelectorPreS.java",
       "java/src/org/chromium/media/AudioManagerAndroid.java",
       "java/src/org/chromium/media/AudioTrackOutputStream.java",
diff --git a/media/base/android/java/src/org/chromium/media/AudioDeviceSelector.java b/media/base/android/java/src/org/chromium/media/AudioDeviceSelector.java
index 2c4f57b..84616da 100644
--- a/media/base/android/java/src/org/chromium/media/AudioDeviceSelector.java
+++ b/media/base/android/java/src/org/chromium/media/AudioDeviceSelector.java
@@ -64,6 +64,12 @@
      */
     protected abstract void setAudioDevice(int device);
 
+    public abstract boolean[] getAvailableDevices_Locked();
+
+    public void setDeviceExistence_Locked(int deviceId, boolean exists) {
+        // Overridden by AudioDeviceSelectorPreS.
+    }
+
     public AudioManagerAndroid.AudioDeviceName[] getAudioInputDeviceNames() {
         return mDeviceStates.getAudioInputDeviceNames();
     }
@@ -78,6 +84,8 @@
 
         int nextDevice = mDeviceStates.setRequestedDeviceIdAndGetNextId(deviceId);
 
+        if (DEBUG) logd("selectDevice: id=" + DeviceHelpers.getDeviceName(nextDevice));
+
         // `deviceId` is invalid, or its corresponding device is not available.
         if (nextDevice == Devices.ID_INVALID) return false;
 
@@ -93,6 +101,8 @@
     protected void maybeUpdateSelectedDevice() {
         int nextDevice = mDeviceStates.getNextDeviceIfRequested();
 
+        if (DEBUG) logd("maybeUpdateSelectedDevice: id=" + DeviceHelpers.getDeviceName(nextDevice));
+
         // No device was explicitly requested.
         if (nextDevice == Devices.ID_INVALID) return;
 
@@ -100,7 +110,7 @@
     }
 
     // Collection of static helpers.
-    private static class DeviceHelpers {
+    protected static class DeviceHelpers {
         // Maps audio device types to string values. This map must be in sync
         // with the Devices.ID_* below.
         // TODO(henrika): add support for proper detection of device names and
@@ -117,6 +127,14 @@
         private static final int ID_VALID_LOWER_BOUND = Devices.ID_SPEAKERPHONE;
         private static final int ID_VALID_UPPER_BOUND = Devices.ID_USB_AUDIO;
 
+        public static String getDeviceName(int deviceId) {
+            if (deviceId == Devices.ID_INVALID) return "invalid-ID";
+
+            if (deviceId == Devices.ID_DEFAULT) return "default-device";
+
+            return DEVICE_NAMES[deviceId];
+        }
+
         /**
          * Use a special selection scheme if the default device is selected.
          * The "most unique" device will be selected; Wired headset first, then USB
@@ -170,14 +188,12 @@
         public static final int ID_EARPIECE = 2;
         public static final int ID_BLUETOOTH_HEADSET = 3;
         public static final int ID_USB_AUDIO = 4;
-        private static final int DEVICE_COUNT = 5;
+        public static final int DEVICE_COUNT = 5;
 
         private Object mLock = new Object();
 
         private int mRequestedAudioDevice = ID_INVALID;
 
-        private boolean[] mDeviceExistence = new boolean[DEVICE_COUNT];
-
         /**
          * Sets the whether a device exists.
          *
@@ -187,8 +203,10 @@
         public void setDeviceExistence(int deviceId, boolean exists) {
             if (!DeviceHelpers.isDeviceValid(deviceId)) return;
 
+            if (DEBUG) logd("Setting [" + DeviceHelpers.getDeviceName(deviceId) + "]=" + exists);
+
             synchronized (mLock) {
-                mDeviceExistence[deviceId] = exists;
+                setDeviceExistence_Locked(deviceId, exists);
             }
         }
 
@@ -243,26 +261,6 @@
         }
 
         /**
-         * Computes the list of available devices based off of exiting devices.
-         * We consider the availability of wired headsets, USB audio and earpices to be
-         * mutually exclusive.
-         */
-        private boolean[] getAvailableDevices_Locked() {
-            boolean[] availableDevices = mDeviceExistence.clone();
-
-            // Wired headset, USB audio and earpiece are mutually exclusive, and
-            // prioritized in that order.
-            if (availableDevices[ID_WIRED_HEADSET]) {
-                availableDevices[ID_USB_AUDIO] = false;
-                availableDevices[ID_EARPIECE] = false;
-            } else if (availableDevices[ID_USB_AUDIO]) {
-                availableDevices[ID_EARPIECE] = false;
-            }
-
-            return availableDevices;
-        }
-
-        /**
          * Returns the list of currently available devices, to be used by the native side.
          */
         public AudioManagerAndroid.AudioDeviceName[] getAudioInputDeviceNames() {
@@ -271,7 +269,9 @@
                 devices = getAvailableDevices_Locked();
             }
             List<String> list = new ArrayList<String>();
+
             int activeDeviceCount = DeviceHelpers.getActiveDeviceCount(devices);
+
             AudioManagerAndroid.AudioDeviceName[] array =
                     new AudioManagerAndroid.AudioDeviceName[activeDeviceCount];
 
@@ -289,6 +289,7 @@
         }
 
         public void clearRequestedDevice() {
+            if (DEBUG) logd("Clearing requested device");
             synchronized (mLock) {
                 mRequestedAudioDevice = ID_INVALID;
             }
diff --git a/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPostS.java b/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPostS.java
new file mode 100644
index 0000000..0831947b
--- /dev/null
+++ b/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPostS.java
@@ -0,0 +1,168 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.media;
+
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import org.chromium.base.Log;
+import org.chromium.base.compat.ApiHelperForS;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RequiresApi(Build.VERSION_CODES.S)
+class AudioDeviceSelectorPostS extends AudioDeviceSelector {
+    private static final String TAG = "media";
+
+    private boolean mHasBluetoothConnectPermission;
+
+    public AudioDeviceSelectorPostS(AudioManager audioManager) {
+        super(audioManager);
+    }
+
+    private static List<Integer> getTargetTypesFromId(int deviceId) {
+        List<Integer> types = new ArrayList<Integer>();
+
+        switch (deviceId) {
+            case Devices.ID_SPEAKERPHONE:
+                types.add(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
+                break;
+            case Devices.ID_WIRED_HEADSET:
+                types.add(AudioDeviceInfo.TYPE_WIRED_HEADSET);
+                types.add(AudioDeviceInfo.TYPE_WIRED_HEADPHONES);
+                break;
+            case Devices.ID_EARPIECE:
+                types.add(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
+                break;
+            case Devices.ID_BLUETOOTH_HEADSET:
+                types.add(AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
+                types.add(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
+                break;
+            case Devices.ID_USB_AUDIO:
+                types.add(AudioDeviceInfo.TYPE_USB_HEADSET);
+                types.add(AudioDeviceInfo.TYPE_USB_DEVICE);
+                break;
+        }
+
+        return types;
+    }
+
+    @Override
+    public void init() {
+        mHasBluetoothConnectPermission = ApiHelperForS.hasBluetoothConnectPermission();
+
+        if (!mHasBluetoothConnectPermission) {
+            Log.w(TAG, "BLUETOOTH_CONNECT permission is missing.");
+        }
+
+        mDeviceListener.init(mHasBluetoothConnectPermission);
+    }
+
+    @Override
+    public void close() {
+        mDeviceListener.close();
+    }
+
+    @Override
+    public void setCommunicationAudioModeOn(boolean on) {
+        if (on) {
+            // TODO(crbug.com/1317548): Prompt for BLUETOOTH_CONNECT permission at this point if we
+            // don't have it.
+        } else {
+            mDeviceStates.clearRequestedDevice();
+            mAudioManager.clearCommunicationDevice();
+        }
+    }
+
+    @Override
+    public boolean isSpeakerphoneOn() {
+        AudioDeviceInfo currentDevice = mAudioManager.getCommunicationDevice();
+        return currentDevice != null
+                && currentDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+    }
+
+    @Override
+    public void setSpeakerphoneOn(boolean on) {
+        boolean isCurrentlyOn = isSpeakerphoneOn();
+
+        if (isCurrentlyOn == on) return;
+
+        if (on) {
+            setAudioDevice(Devices.ID_SPEAKERPHONE);
+        } else {
+            // Turn speakerphone OFF.
+            mAudioManager.clearCommunicationDevice();
+            maybeUpdateSelectedDevice();
+        }
+    }
+
+    @Override
+    public boolean[] getAvailableDevices_Locked() {
+        List<AudioDeviceInfo> communicationDevices =
+                mAudioManager.getAvailableCommunicationDevices();
+
+        boolean[] availableDevices = new boolean[Devices.DEVICE_COUNT];
+
+        for (AudioDeviceInfo device : communicationDevices) {
+            switch (device.getType()) {
+                case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
+                    availableDevices[Devices.ID_SPEAKERPHONE] = true;
+                    break;
+
+                case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
+                case AudioDeviceInfo.TYPE_WIRED_HEADSET:
+                    availableDevices[Devices.ID_WIRED_HEADSET] = true;
+                    break;
+
+                case AudioDeviceInfo.TYPE_USB_DEVICE:
+                case AudioDeviceInfo.TYPE_USB_HEADSET:
+                    availableDevices[Devices.ID_USB_AUDIO] = true;
+                    break;
+
+                case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
+                case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
+                    availableDevices[Devices.ID_BLUETOOTH_HEADSET] = true;
+                    break;
+
+                case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
+                    availableDevices[Devices.ID_EARPIECE] = true;
+                    break;
+            }
+        }
+
+        return availableDevices;
+    }
+
+    public AudioDeviceInfo getMatchingCommunicationDevice(List<Integer> targetTypes) {
+        List<AudioDeviceInfo> availableDevices = mAudioManager.getAvailableCommunicationDevices();
+
+        for (AudioDeviceInfo device : availableDevices) {
+            if (targetTypes.contains(device.getType())) return device;
+        }
+
+        return null;
+    }
+
+    @Override
+    protected void setAudioDevice(int deviceId) {
+        if (!DeviceHelpers.isDeviceValid(deviceId)) return;
+
+        AudioDeviceInfo targetDevice =
+                getMatchingCommunicationDevice(getTargetTypesFromId(deviceId));
+
+        if (targetDevice != null) {
+            boolean result = mAudioManager.setCommunicationDevice(targetDevice);
+            if (!result) {
+                loge("Error setting communication device");
+            }
+        } else {
+            loge("Couldn't find available device for: " + DeviceHelpers.getDeviceName(deviceId));
+        }
+    }
+}
\ No newline at end of file
diff --git a/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPreS.java b/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPreS.java
index 527da8b..87228b0 100644
--- a/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPreS.java
+++ b/media/base/android/java/src/org/chromium/media/AudioDeviceSelectorPreS.java
@@ -10,10 +10,8 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.media.AudioManager;
-import android.os.Build;
 
 import org.chromium.base.ContextUtils;
-import org.chromium.base.compat.ApiHelperForS;
 
 class AudioDeviceSelectorPreS extends AudioDeviceSelector {
     private static final String TAG = "media";
@@ -33,6 +31,8 @@
 
     private boolean mHasBluetoothPermission;
 
+    private boolean[] mDeviceExistence = new boolean[Devices.DEVICE_COUNT];
+
     public AudioDeviceSelectorPreS(AudioManager audioManager) {
         super(audioManager);
     }
@@ -45,12 +45,6 @@
     public void init() {
         mHasBluetoothPermission = hasPermission(android.Manifest.permission.BLUETOOTH);
 
-        // TODO(crbug.com/1317548): Remove this check once there is an AudioDeviceSelector
-        // for S and above.
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
-            mHasBluetoothPermission &= ApiHelperForS.hasBluetoothConnectPermission();
-        }
-
         mDeviceListener.init(mHasBluetoothPermission);
 
         if (mHasBluetoothPermission) registerForBluetoothScoIntentBroadcast();
@@ -84,6 +78,27 @@
         mAudioManager.setSpeakerphoneOn(on);
     }
 
+    @Override
+    public boolean[] getAvailableDevices_Locked() {
+        boolean[] availableDevices = mDeviceExistence.clone();
+
+        // Wired headset, USB audio and earpiece are mutually exclusive, and
+        // prioritized in that order.
+        if (availableDevices[Devices.ID_WIRED_HEADSET]) {
+            availableDevices[Devices.ID_USB_AUDIO] = false;
+            availableDevices[Devices.ID_EARPIECE] = false;
+        } else if (availableDevices[Devices.ID_USB_AUDIO]) {
+            availableDevices[Devices.ID_EARPIECE] = false;
+        }
+
+        return availableDevices;
+    }
+
+    @Override
+    public void setDeviceExistence_Locked(int deviceId, boolean exists) {
+        mDeviceExistence[deviceId] = exists;
+    }
+
     /** Checks if the process has as specified permission or not. */
     private boolean hasPermission(String permission) {
         return ContextUtils.getApplicationContext().checkSelfPermission(permission)
@@ -125,7 +140,7 @@
                         // do nothing
                         break;
                     default:
-                        loge("Invalid state");
+                        break;
                 }
             }
         };
diff --git a/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java b/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java
index 2056357b..bf772e2 100644
--- a/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/AudioManagerAndroid.java
@@ -98,9 +98,11 @@
                 Context.AUDIO_SERVICE);
         mContentResolver = ContextUtils.getApplicationContext().getContentResolver();
 
-        // TODO(crbug.com/1317548): For now, we also use AudioDeviceSelectorPreS on Android S and
-        // above. Fix this by adding an S and above implementation.
-        mAudioDeviceSelector = new AudioDeviceSelectorPreS(mAudioManager);
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
+            mAudioDeviceSelector = new AudioDeviceSelectorPreS(mAudioManager);
+        } else {
+            mAudioDeviceSelector = new AudioDeviceSelectorPostS(mAudioManager);
+        }
     }
 
     /**
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc
index d7c85e2..4307df3 100644
--- a/net/reporting/reporting_service_unittest.cc
+++ b/net/reporting/reporting_service_unittest.cc
@@ -325,7 +325,12 @@
       context()->cache()->GetExpiredSources().contains(kReportingSource_));
 }
 
-TEST_P(ReportingServiceTest, ProcessReportingEndpointsHeaderPathAbsolute) {
+#if BUILDFLAG(IS_CHROMEOS)
+#define MAYBE_ProcessReportingEndpointsHeaderPathAbsolute DISABLED_ProcessReportingEndpointsHeaderPathAbsolute
+#else
+#define MAYBE_ProcessReportingEndpointsHeaderPathAbsolute ProcessReportingEndpointsHeaderPathAbsolute
+#endif
+TEST_P(ReportingServiceTest, MAYBE_ProcessReportingEndpointsHeaderPathAbsolute) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(net::features::kDocumentReporting);
   auto parsed_header = ParseReportingEndpoints(kGroup_ + "=\"/path-absolute\"");
diff --git a/remoting/host/desktop_resizer_x11.cc b/remoting/host/desktop_resizer_x11.cc
index 8505c61..0031489 100644
--- a/remoting/host/desktop_resizer_x11.cc
+++ b/remoting/host/desktop_resizer_x11.cc
@@ -49,6 +49,7 @@
 namespace {
 
 constexpr auto kInvalidMode = static_cast<x11::RandR::Mode>(0);
+constexpr auto kDisabledCrtc = static_cast<x11::RandR::Crtc>(0);
 
 int PixelsToMillimeters(int pixels, int dpi) {
   DCHECK(dpi != 0);
@@ -91,16 +92,6 @@
   return kInvalidMode;
 }
 
-x11::RandR::Output ScreenResources::GetOutput() {
-  CHECK(resources_);
-  return resources_->outputs[0];
-}
-
-x11::RandR::Crtc ScreenResources::GetCrtc() {
-  CHECK(resources_);
-  return resources_->crtcs[0];
-}
-
 x11::RandR::GetScreenResourcesCurrentReply* ScreenResources::get() {
   return resources_.get();
 }
@@ -187,8 +178,14 @@
   // that the display configuration doesn't change under our feet.
   ScopedXGrabServer grabber(connection_);
 
+  if (!resources_.Refresh(randr_, root_))
+    return;
+
+  // TODO(crbug.com/1326339): Instead of hard-coding the first output, find the
+  // one attached to the RANDR monitor |screen_id|.
+  x11::RandR::Output output = resources_.get()->outputs[0];
   if (exact_resize_)
-    SetResolutionNewMode(resolution);
+    SetResolutionNewMode(output, resolution);
   else
     SetResolutionExistingMode(resolution);
 }
@@ -199,6 +196,7 @@
 }
 
 void DesktopResizerX11::SetResolutionNewMode(
+    x11::RandR::Output output,
     const ScreenResolution& resolution) {
   // The name of the mode representing the current client view resolution and
   // the temporary mode used for the reasons described at the top of this file.
@@ -219,19 +217,19 @@
       PixelsToMillimeters(resolution.dimensions().width(), kDefaultDPI);
   uint32_t height_mm =
       PixelsToMillimeters(resolution.dimensions().height(), kDefaultDPI);
-  CreateMode(kTempModeName, resolution.dimensions().width(),
+  CreateMode(output, kTempModeName, resolution.dimensions().width(),
              resolution.dimensions().height());
-  SwitchToMode(nullptr);
+  SwitchToMode(output, nullptr);
   randr_->SetScreenSize(
       {root_, static_cast<uint16_t>(resolution.dimensions().width()),
        static_cast<uint16_t>(resolution.dimensions().height()), width_mm,
        height_mm});
-  SwitchToMode(kTempModeName);
-  DeleteMode(kModeName);
-  CreateMode(kModeName, resolution.dimensions().width(),
+  SwitchToMode(output, kTempModeName);
+  DeleteMode(output, kModeName);
+  CreateMode(output, kModeName, resolution.dimensions().width(),
              resolution.dimensions().height());
-  SwitchToMode(kModeName);
-  DeleteMode(kTempModeName);
+  SwitchToMode(output, kModeName);
+  DeleteMode(output, kTempModeName);
 }
 
 void DesktopResizerX11::SetResolutionExistingMode(
@@ -256,7 +254,10 @@
   }
 }
 
-void DesktopResizerX11::CreateMode(const char* name, int width, int height) {
+void DesktopResizerX11::CreateMode(x11::RandR::Output output,
+                                   const char* name,
+                                   int width,
+                                   int height) {
   x11::RandR::ModeInfo mode;
   mode.width = width;
   mode.height = height;
@@ -266,36 +267,72 @@
   if (!resources_.Refresh(randr_, root_))
     return;
   x11::RandR::Mode mode_id = resources_.GetIdForMode(name);
-  if (mode_id == kInvalidMode)
+  if (mode_id == kInvalidMode) {
+    LOG(ERROR) << "No ID found for mode: " << name;
     return;
+  }
   randr_->AddOutputMode({
-      resources_.GetOutput(),
+      output,
       mode_id,
   });
 }
 
-void DesktopResizerX11::DeleteMode(const char* name) {
+void DesktopResizerX11::DeleteMode(x11::RandR::Output output,
+                                   const char* name) {
   x11::RandR::Mode mode_id = resources_.GetIdForMode(name);
   if (mode_id != kInvalidMode) {
-    randr_->DeleteOutputMode({resources_.GetOutput(), mode_id});
+    randr_->DeleteOutputMode({output, mode_id});
     randr_->DestroyMode({mode_id});
     resources_.Refresh(randr_, root_);
   }
 }
 
-void DesktopResizerX11::SwitchToMode(const char* name) {
+void DesktopResizerX11::SwitchToMode(x11::RandR::Output output,
+                                     const char* name) {
   auto mode_id = kInvalidMode;
   std::vector<x11::RandR::Output> outputs;
   if (name) {
     mode_id = resources_.GetIdForMode(name);
-    CHECK_NE(mode_id, kInvalidMode);
-    outputs = resources_.get()->outputs;
+    if (mode_id == kInvalidMode) {
+      LOG(ERROR) << "No ID found for mode: " << name;
+      return;
+    }
+
+    // The case where a CRTC has multiple outputs is unsupported here. With
+    // Xvfb, there exists only 1 output. With Xorg+video-dummy, there are
+    // several outputs, but each one has a separate CRTC it can attach to.
+    outputs = {output};
   }
-  const auto* resources = resources_.get();
+
+  x11::Time config_timestamp = resources_.get()->config_timestamp;
+  auto output_info = randr_->GetOutputInfo({output, config_timestamp}).Sync();
+  if (!output_info)
+    return;
+
+  x11::RandR::Crtc crtc = output_info->crtc;
+  if (crtc == kDisabledCrtc) {
+    // The output is disabled. If |name| is nullptr, the caller requested the
+    // output be disabled, so there is nothing further to do.
+    if (!name)
+      return;
+
+    // |crtcs| is the set of CRTCs that this output is allowed to attach to.
+    if (output_info->crtcs.size() != 1) {
+      // |crtcs| should always be non-empty. To properly handle the size() > 1
+      // case, the code should step through |crtcs| and fetch the outputs using
+      // GetCrtcInfo(), stopping when a CRTC is found with empty outputs. With
+      // Xorg+video-dummy, this case never happens - the driver allocates a
+      // single CRTC for each output.
+      LOG(ERROR) << "Unexpected #crtcs: " << output_info->crtcs.size();
+      return;
+    }
+    crtc = output_info->crtcs[0];
+  }
+
   randr_->SetCrtcConfig({
-      .crtc = resources_.GetCrtc(),
+      .crtc = crtc,
       .timestamp = x11::Time::CurrentTime,
-      .config_timestamp = resources->config_timestamp,
+      .config_timestamp = config_timestamp,
       .x = 0,
       .y = 0,
       .mode = mode_id,
diff --git a/remoting/host/desktop_resizer_x11.h b/remoting/host/desktop_resizer_x11.h
index 1d446f8..54f35fc 100644
--- a/remoting/host/desktop_resizer_x11.h
+++ b/remoting/host/desktop_resizer_x11.h
@@ -27,12 +27,6 @@
 
   x11::RandR::Mode GetIdForMode(const std::string& name);
 
-  // For now, assume we're only ever interested in the first output.
-  x11::RandR::Output GetOutput();
-
-  // For now, assume we're only ever interested in the first crtc.
-  x11::RandR::Crtc GetCrtc();
-
   x11::RandR::GetScreenResourcesCurrentReply* get();
 
  private:
@@ -58,24 +52,27 @@
 
  private:
   // Add a mode matching the specified resolution and switch to it.
-  void SetResolutionNewMode(const ScreenResolution& resolution);
+  void SetResolutionNewMode(x11::RandR::Output output,
+                            const ScreenResolution& resolution);
 
   // Attempt to switch to an existing mode matching the specified resolution
   // using RandR, if such a resolution exists. Otherwise, do nothing.
   void SetResolutionExistingMode(const ScreenResolution& resolution);
 
-  // Create a mode, and attach it to the primary output. If the mode already
-  // exists, it is left unchanged.
-  void CreateMode(const char* name, int width, int height);
+  // Create a mode, and attach it to the output. If the mode already exists, it
+  // is left unchanged.
+  void CreateMode(x11::RandR::Output output,
+                  const char* name,
+                  int width,
+                  int height);
 
-  // Remove the specified mode from the primary output, and delete it. If the
-  // mode is in use, it is not deleted.
-  void DeleteMode(const char* name);
+  // Remove the specified mode from the output, and delete it. If the mode is in
+  // use, it is not deleted.
+  void DeleteMode(x11::RandR::Output output, const char* name);
 
-  // Switch the primary output to the specified mode. If name is nullptr, the
-  // primary output is disabled instead, which is required before changing
-  // its resolution.
-  void SwitchToMode(const char* name);
+  // Switch the output to the specified mode. If name is nullptr, the output is
+  // disabled instead, which is required before changing its resolution.
+  void SwitchToMode(x11::RandR::Output output, const char* name);
 
   raw_ptr<x11::Connection> connection_;
   const raw_ptr<x11::RandR> randr_ = nullptr;
diff --git a/remoting/host/linux/linux_me2me_host.py b/remoting/host/linux/linux_me2me_host.py
index dddf6a0..7b49ff4c 100755
--- a/remoting/host/linux/linux_me2me_host.py
+++ b/remoting/host/linux/linux_me2me_host.py
@@ -1099,7 +1099,7 @@
         suffix=".conf", delete=False) as config_file:
       config_file.write(gen_xorg_config().encode())
 
-    self.server_supports_exact_resize = False
+    self.server_supports_exact_resize = True
     self.server_supports_randr = True
     self.randr_add_sizes = True
     self.xorg_conf = config_file.name
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 0f55d68..d03e519 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -881,16 +881,18 @@
       "ext/test_fonts.h",
       "ext/test_fonts_fuchsia.h",
     ]
-    sources = [ "ext/test_fonts_fuchsia.cc" ]
-    public_deps = [
-      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts",
-      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sys",
-      "//third_party/fuchsia-sdk/sdk/pkg/fidl_cpp_base",
+    sources = [
+      "ext/test_fonts_fuchsia.cc",
+      "ext/test_fonts_fuchsia_cfv1.cc",
     ]
+    public_deps = [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts" ]
     deps += [
       "//base",
       "//skia",
+      "//third_party/abseil-cpp:absl",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.io",
+      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sys",
+      "//third_party/fuchsia-sdk/sdk/pkg/fidl_cpp_base",
       "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
     ]
   }
@@ -949,11 +951,7 @@
     # args.
     use_cfv2 = false
     sources += [ "ext/fontmgr_fuchsia_unittest.cc" ]
-    deps += [
-      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts",
-      "//third_party/test_fonts",
-    ]
-    data_deps += [ "//third_party/test_fonts" ]
+    deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts" ]
   }
 
   if (skia_support_skottie) {
diff --git a/skia/ext/fontmgr_fuchsia_unittest.cc b/skia/ext/fontmgr_fuchsia_unittest.cc
index 7ac1aaa0..c035c7b6 100644
--- a/skia/ext/fontmgr_fuchsia_unittest.cc
+++ b/skia/ext/fontmgr_fuchsia_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include <fuchsia/fonts/cpp/fidl.h>
-#include <lib/fidl/cpp/binding.h>
 
 #include "skia/ext/test_fonts_fuchsia.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -16,14 +15,11 @@
 // Tests for SkFontMgr_Fuchsia in Skia.
 class FuchsiaFontManagerTest : public testing::Test {
  public:
-  FuchsiaFontManagerTest() {
-    font_manager_ = SkFontMgr_New_Fuchsia(
-        RunTestProviderWithTestFonts(&font_provider_controller_));
-  }
+  FuchsiaFontManagerTest()
+      : font_manager_(
+            SkFontMgr_New_Fuchsia(GetTestFontsProvider().BindSync())) {}
 
  protected:
-  fidl::InterfaceHandle<fuchsia::sys::ComponentController>
-      font_provider_controller_;
   sk_sp<SkFontMgr> font_manager_;
 };
 
diff --git a/skia/ext/test_fonts.h b/skia/ext/test_fonts.h
index c2e54456..c3120272 100644
--- a/skia/ext/test_fonts.h
+++ b/skia/ext/test_fonts.h
@@ -9,7 +9,7 @@
 
 // Configures the process to use //third_party/test_fonts. Should be called
 // early, before default instance of SkFontMgr is created.
-void ConfigureTestFont();
+void InitializeSkFontMgrForTest();
 
 }  // namespace skia
 
diff --git a/skia/ext/test_fonts_fuchsia.cc b/skia/ext/test_fonts_fuchsia.cc
index cab73b6..23ffc913 100644
--- a/skia/ext/test_fonts_fuchsia.cc
+++ b/skia/ext/test_fonts_fuchsia.cc
@@ -5,70 +5,16 @@
 #include "skia/ext/test_fonts_fuchsia.h"
 
 #include <fuchsia/fonts/cpp/fidl.h>
-#include <fuchsia/io/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
-#include <lib/fidl/cpp/interface_handle.h>
-#include <lib/sys/cpp/component_context.h>
 
-#include "base/check.h"
-#include "base/fuchsia/file_utils.h"
-#include "base/fuchsia/process_context.h"
-#include "base/logging.h"
-#include "base/no_destructor.h"
-#include "base/path_service.h"
 #include "skia/ext/fontmgr_default.h"
-#include "skia/ext/test_fonts.h"
 #include "third_party/skia/include/core/SkFontMgr.h"
 #include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"
 
 namespace skia {
 
-fuchsia::fonts::ProviderSyncPtr RunTestProviderWithTestFonts(
-    fidl::InterfaceHandle<fuchsia::sys::ComponentController>* controller_out) {
-  // Start a fuchsia.fonts.Provider instance and configure it to load the test
-  // fonts, which must be bundled in the calling process' package.
-  fuchsia::sys::LaunchInfo launch_info;
-  launch_info.url = "fuchsia-pkg://fuchsia.com/fonts#meta/fonts.cmx";
-  launch_info.arguments.emplace(
-      {"--font-manifest", "/test_fonts/fuchsia_test_fonts_manifest.json"});
-  launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New();
-  launch_info.flat_namespace->paths.push_back("/test_fonts");
-
-  base::FilePath assets_path;
-  if (!base::PathService::Get(base::DIR_ASSETS, &assets_path))
-    LOG(FATAL) << "Can't get DIR_ASSETS";
-  launch_info.flat_namespace->directories.push_back(
-      base::OpenDirectoryHandle(assets_path.AppendASCII("test_fonts"))
-          .TakeChannel());
-
-  fidl::InterfaceHandle<fuchsia::io::Directory> font_provider_services_dir;
-  launch_info.directory_request =
-      font_provider_services_dir.NewRequest().TakeChannel();
-
-  fuchsia::sys::LauncherSyncPtr launcher;
-  base::ComponentContextForProcess()->svc()->Connect(launcher.NewRequest());
-  launcher->CreateComponent(std::move(launch_info),
-                            controller_out->NewRequest());
-
-  sys::ServiceDirectory font_provider_services_client(
-      std::move(font_provider_services_dir));
-
-  fuchsia::fonts::ProviderSyncPtr provider;
-  font_provider_services_client.Connect(provider.NewRequest());
-  return provider;
-}
-
-void ConfigureTestFont() {
-  // ComponentController for the font provider service started below. It's a
-  // static field to keep the service running until the test process is
-  // destroyed.
-  static base::NoDestructor<
-      fidl::InterfaceHandle<fuchsia::sys::ComponentController>>
-      test_font_provider_controller;
-  DCHECK(!*test_font_provider_controller);
-
-  skia::OverrideDefaultSkFontMgr(SkFontMgr_New_Fuchsia(
-      RunTestProviderWithTestFonts(test_font_provider_controller.get())));
+void InitializeSkFontMgrForTest() {
+  OverrideDefaultSkFontMgr(
+      SkFontMgr_New_Fuchsia(GetTestFontsProvider().BindSync()));
 }
 
 }  // namespace skia
diff --git a/skia/ext/test_fonts_fuchsia.h b/skia/ext/test_fonts_fuchsia.h
index f7aefac..4739bee 100644
--- a/skia/ext/test_fonts_fuchsia.h
+++ b/skia/ext/test_fonts_fuchsia.h
@@ -6,12 +6,12 @@
 #define SKIA_EXT_TEST_FONTS_FUCHSIA_H_
 
 #include <fuchsia/fonts/cpp/fidl.h>
-#include <fuchsia/sys/cpp/fidl.h>
 
 namespace skia {
 
-fuchsia::fonts::ProviderSyncPtr RunTestProviderWithTestFonts(
-    fidl::InterfaceHandle<fuchsia::sys::ComponentController>* controller_out);
+// Returns a handle to a fuchsia.fonts.Provider that serves the fonts in
+// the package's test_fonts directory.
+fuchsia::fonts::ProviderHandle GetTestFontsProvider();
 
 }  // namespace skia
 
diff --git a/skia/ext/test_fonts_fuchsia_cfv1.cc b/skia/ext/test_fonts_fuchsia_cfv1.cc
new file mode 100644
index 0000000..de3d1dc
--- /dev/null
+++ b/skia/ext/test_fonts_fuchsia_cfv1.cc
@@ -0,0 +1,89 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "skia/ext/test_fonts_fuchsia.h"
+
+#include <fuchsia/fonts/cpp/fidl.h>
+#include <fuchsia/io/cpp/fidl.h>
+#include <fuchsia/sys/cpp/fidl.h>
+#include <lib/fidl/cpp/interface_handle.h>
+#include <lib/sys/cpp/component_context.h>
+
+#include <utility>
+
+#include "base/check.h"
+#include "base/files/file_path.h"
+#include "base/fuchsia/file_utils.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
+#include "base/no_destructor.h"
+#include "base/path_service.h"
+#include "skia/ext/test_fonts.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace skia {
+
+namespace {
+
+// Runs the fonts component via fuchsia.sys.Launcher.
+class TestFontsProvider {
+ public:
+  TestFontsProvider();
+  TestFontsProvider(const TestFontsProvider&) = delete;
+  TestFontsProvider& operator=(const TestFontsProvider&) = delete;
+  ~TestFontsProvider();
+
+  fuchsia::fonts::ProviderHandle GetProvider();
+
+ private:
+  fidl::InterfaceHandle<fuchsia::sys::ComponentController> controller_;
+  absl::optional<sys::ServiceDirectory> services_client_;
+};
+
+TestFontsProvider::TestFontsProvider() {
+  // Start a fuchsia.fonts.Provider instance and configure it to load the test
+  // fonts, which must be bundled in the calling process' package.
+  fuchsia::sys::LaunchInfo launch_info;
+  launch_info.url = "fuchsia-pkg://fuchsia.com/fonts#meta/fonts.cmx";
+  launch_info.arguments.emplace(
+      {"--font-manifest", "/test_fonts/fuchsia_test_fonts_manifest.json"});
+  launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New();
+  launch_info.flat_namespace->paths.push_back("/test_fonts");
+
+  base::FilePath assets_path;
+  CHECK(base::PathService::Get(base::DIR_ASSETS, &assets_path))
+      << "Can't get DIR_ASSETS";
+  launch_info.flat_namespace->directories.push_back(
+      base::OpenDirectoryHandle(assets_path.AppendASCII("test_fonts"))
+          .TakeChannel());
+
+  fidl::InterfaceHandle<fuchsia::io::Directory> font_provider_services_dir;
+  launch_info.directory_request =
+      font_provider_services_dir.NewRequest().TakeChannel();
+
+  fuchsia::sys::LauncherSyncPtr launcher;
+  auto status =
+      base::ComponentContextForProcess()->svc()->Connect(launcher.NewRequest());
+  ZX_CHECK(status == ZX_OK, status) << "Connect to fuchsia.sys.Launcher";
+  launcher->CreateComponent(std::move(launch_info), controller_.NewRequest());
+
+  services_client_.emplace(std::move(font_provider_services_dir));
+}
+
+TestFontsProvider::~TestFontsProvider() = default;
+
+fuchsia::fonts::ProviderHandle TestFontsProvider::GetProvider() {
+  fuchsia::fonts::ProviderHandle font_provider;
+  services_client_->Connect(font_provider.NewRequest());
+  return font_provider;
+}
+
+}  // namespace
+
+fuchsia::fonts::ProviderHandle GetTestFontsProvider() {
+  static base::NoDestructor<TestFontsProvider> test_fonts_provider;
+  return test_fonts_provider->GetProvider();
+}
+
+}  // namespace skia
diff --git a/skia/ext/test_fonts_mac.mm b/skia/ext/test_fonts_mac.mm
index a6e438f..fe48e589 100644
--- a/skia/ext/test_fonts_mac.mm
+++ b/skia/ext/test_fonts_mac.mm
@@ -14,7 +14,7 @@
 
 namespace skia {
 
-void ConfigureTestFont() {
+void InitializeSkFontMgrForTest() {
   // Load font files in the resource folder.
   static const char* const kFontFileNames[] = {"Ahem.ttf",
                                                "ChromiumAATTest.ttf"};
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index 4bc6b2f..792b909cc 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -856,6 +856,10 @@
   g_clock_for_testing = clock;
 }
 
+void QuotaDatabase::CommitNow() {
+  Commit();
+}
+
 void QuotaDatabase::Commit() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!db_)
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index 4537bbd..0bdbe80 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -215,6 +215,9 @@
   // one doesn't exist.
   QuotaError RazeAndReopen();
 
+  // Flushes previously scheduled commits.
+  void CommitNow();
+
   // Testing support for database corruption handling.
   //
   // Runs `corrupter` on the same sequence used to do database I/O,
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc
index f0a13738..262ca6f 100644
--- a/storage/browser/quota/quota_manager_impl.cc
+++ b/storage/browser/quota/quota_manager_impl.cc
@@ -647,11 +647,13 @@
       QuotaManagerImpl* manager,
       const BucketLocator& bucket,
       QuotaClientTypes quota_client_types,
+      bool commit_immediately,
       base::OnceCallback<void(BucketDataDeleter*,
                               blink::mojom::QuotaStatusCode)> callback)
       : manager_(manager),
         bucket_(bucket),
         quota_client_types_(std::move(quota_client_types)),
+        commit_immediately_(commit_immediately),
         callback_(std::move(callback)) {
     DCHECK(manager_);
     // TODO(crbug/1292216): Convert back into DCHECKs once issue is resolved.
@@ -737,7 +739,7 @@
     // types.
     if (skipped_clients_ == 0 && error_count_ == 0) {
       manager_->DeleteBucketFromDatabase(
-          bucket_,
+          bucket_, commit_immediately_,
           base::BindOnce(&BucketDataDeleter::DidDeleteBucketFromDatabase,
                          weak_factory_.GetWeakPtr()));
       return;
@@ -769,6 +771,9 @@
       GUARDED_BY_CONTEXT(sequence_checker_);
   const BucketLocator bucket_;
   const QuotaClientTypes quota_client_types_;
+  // Whether the update to the database should be committed immediately (if not,
+  // it will be scheduled to be committed as part of a batch).
+  const bool commit_immediately_;
   int error_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
   size_t remaining_clients_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
   int skipped_clients_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
@@ -854,7 +859,7 @@
       // BucketDataDeleter created here, which guarantees it will only use the
       // callback when it's alive.
       auto bucket_deleter = std::make_unique<BucketDataDeleter>(
-          manager_, bucket, AllQuotaClientTypes(),
+          manager_, bucket, AllQuotaClientTypes(), /*commit_immediately=*/false,
           base::BindOnce(&HostDataDeleter::DidDeleteBucketData,
                          base::Unretained(this)));
       auto* bucket_deleter_ptr = bucket_deleter.get();
@@ -2141,6 +2146,7 @@
 
 void QuotaManagerImpl::DeleteBucketFromDatabase(
     const BucketLocator& bucket,
+    bool commit_immediately,
     base::OnceCallback<void(QuotaError)> callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
@@ -2153,11 +2159,16 @@
 
   PostTaskAndReplyWithResultForDBThread(
       base::BindOnce(
-          [](const BucketLocator& bucket, QuotaDatabase* database) {
+          [](const BucketLocator& bucket, bool commit_immediately,
+             QuotaDatabase* database) {
             DCHECK(database);
-            return database->DeleteBucketData(bucket);
+            auto result = database->DeleteBucketData(bucket);
+            if (commit_immediately && result == QuotaError::kNone)
+              database->CommitNow();
+
+            return result;
           },
-          bucket),
+          bucket, commit_immediately),
       std::move(callback));
 }
 
@@ -2200,7 +2211,7 @@
     return;
   }
   auto bucket_deleter = std::make_unique<BucketDataDeleter>(
-      this, bucket, std::move(quota_client_types),
+      this, bucket, std::move(quota_client_types), /*commit_immediately=*/true,
       base::BindOnce(&QuotaManagerImpl::DidDeleteBucketData,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
   auto* bucket_deleter_ptr = bucket_deleter.get();
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h
index 75ffaf9..012348a 100644
--- a/storage/browser/quota/quota_manager_impl.h
+++ b/storage/browser/quota/quota_manager_impl.h
@@ -633,6 +633,7 @@
   // Methods for eviction logic.
   void StartEviction();
   void DeleteBucketFromDatabase(const BucketLocator& bucket,
+                                bool commit_immediately,
                                 base::OnceCallback<void(QuotaError)> callback);
 
   void DidBucketDataEvicted(mojom::BucketTableEntryPtr entry,
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index bee67d3..1928ece 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -41302,6 +41302,5010 @@
       }
     ]
   },
+  "android-pie-x86-fyi-rel-reviver": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "absl_hardening_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "absl_hardening_tests",
+        "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "android_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "android_browsertests",
+        "test_id_prefix": "ninja://chrome/test:android_browsertests/"
+      },
+      {
+        "args": [
+          "--test-launcher-batch-limit=1",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "android_sync_integration_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "android_sync_integration_tests",
+        "test_id_prefix": "ninja://chrome/test:android_sync_integration_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "android_webview_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "android_webview_unittests",
+        "test_id_prefix": "ninja://android_webview/test:android_webview_unittests/"
+      },
+      {
+        "args": [
+          "-v",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "os": "Ubuntu-18.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "generic_android28",
+              "path": ".android_emulator/generic_android28"
+            }
+          ],
+          "optional_dimensions": {
+            "60": [
+              {
+                "caches": "generic_android28"
+              }
+            ]
+          },
+          "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": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "base_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "base_unittests",
+        "test_id_prefix": "ninja://base:base_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_common_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "blink_common_unittests",
+        "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_heap_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "blink_heap_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "blink_platform_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "blink_platform_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webkit_unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "webkit_unit_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 6
+        },
+        "test": "blink_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "boringssl_crypto_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "boringssl_crypto_tests",
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "boringssl_ssl_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "boringssl_ssl_tests",
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "breakpad_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "breakpad_unittests",
+        "test_id_prefix": "ninja://third_party/breakpad:breakpad_unittests/"
+      },
+      {
+        "args": [
+          "--gtest_filter=-*UsingRealWebcam*",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "capture_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "capture_unittests",
+        "test_id_prefix": "ninja://media/capture:capture_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "cast_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "cast_unittests",
+        "test_id_prefix": "ninja://media/cast:cast_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "cc_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "cc_unittests",
+        "test_id_prefix": "ninja://cc:cc_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_java_test_pagecontroller_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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_java_test_pagecontroller_tests",
+        "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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_smoke_test",
+        "test_id_prefix": "ninja://chrome/android:chrome_public_smoke_test/"
+      },
+      {
+        "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",
+          "--gtest_also_run_disabled_tests",
+          "--git-revision=${got_revision}"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "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,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "e2-standard-8",
+              "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",
+          "shards": 20
+        },
+        "test": "chrome_public_test_apk",
+        "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
+      },
+      {
+        "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",
+          "--gtest_also_run_disabled_tests",
+          "--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,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "--gtest_also_run_disabled_tests",
+          "--git-revision=${got_revision}"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "chrome_public_unit_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "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,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 4
+        },
+        "test": "chrome_public_unit_test_apk",
+        "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "components_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "components_browsertests",
+        "test_id_prefix": "ninja://components:components_browsertests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "components_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 6
+        },
+        "test": "components_unittests",
+        "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 15
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_shell_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 3
+        },
+        "test": "content_shell_test_apk",
+        "test_id_prefix": "ninja://content/shell/android:content_shell_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "content_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 3
+        },
+        "test": "content_unittests",
+        "test_id_prefix": "ninja://content/test:content_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "crashpad_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "crashpad_tests",
+        "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "crypto_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "crypto_unittests",
+        "test_id_prefix": "ninja://crypto:crypto_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "device_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "device_unittests",
+        "test_id_prefix": "ninja://device:device_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "display_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "display_unittests",
+        "test_id_prefix": "ninja://ui/display:display_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "events_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "events_unittests",
+        "test_id_prefix": "ninja://ui/events:events_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gcm_unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gcm_unit_tests",
+        "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gfx_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gfx_unittests",
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gin_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gin_unittests",
+        "test_id_prefix": "ninja://gin:gin_unittests/"
+      },
+      {
+        "args": [
+          "--use-cmd-decoder=validating",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gl_tests_validating"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "gl_tests_validating",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gl_tests",
+        "test_id_prefix": "ninja://gpu:gl_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gl_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gl_unittests",
+        "test_id_prefix": "ninja://ui/gl:gl_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "google_apis_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "google_apis_unittests",
+        "test_id_prefix": "ninja://google_apis:google_apis_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gpu_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gpu_unittests",
+        "test_id_prefix": "ninja://gpu:gpu_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "gwp_asan_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "gwp_asan_unittests",
+        "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ipc_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "ipc_tests",
+        "test_id_prefix": "ninja://ipc:ipc_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "latency_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "latency_unittests",
+        "test_id_prefix": "ninja://ui/latency:latency_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "libjingle_xmpp_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "libjingle_xmpp_unittests",
+        "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "liburlpattern_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "liburlpattern_unittests",
+        "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "media_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "media_unittests",
+        "test_id_prefix": "ninja://media:media_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "midi_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "midi_unittests",
+        "test_id_prefix": "ninja://media/midi:midi_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "mojo_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "mojo_test_apk",
+        "test_id_prefix": "ninja://mojo/public/java/system:mojo_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "mojo_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "mojo_unittests",
+        "test_id_prefix": "ninja://mojo:mojo_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "monochrome_public_bundle_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "monochrome_public_bundle_smoke_test",
+        "test_id_prefix": "ninja://chrome/android:monochrome_public_bundle_smoke_test/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "monochrome_public_smoke_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "monochrome_public_smoke_test",
+        "test_id_prefix": "ninja://chrome/android:monochrome_public_smoke_test/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "net_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 3
+        },
+        "test": "net_unittests",
+        "test_id_prefix": "ninja://net:net_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "perfetto_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "perfetto_unittests",
+        "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "sandbox_linux_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "sandbox_linux_unittests",
+        "test_id_prefix": "ninja://sandbox/linux:sandbox_linux_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "services_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "services_unittests",
+        "test_id_prefix": "ninja://services:services_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "shell_dialogs_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "shell_dialogs_unittests",
+        "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "skia_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "skia_unittests",
+        "test_id_prefix": "ninja://skia:skia_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "sql_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "sql_unittests",
+        "test_id_prefix": "ninja://sql:sql_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "storage_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "storage_unittests",
+        "test_id_prefix": "ninja://storage:storage_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "system_webview_shell_layout_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "system_webview_shell_layout_test_apk",
+        "test_id_prefix": "ninja://android_webview/tools/system_webview_shell:system_webview_shell_layout_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_android_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "ui_android_unittests",
+        "test_id_prefix": "ninja://ui/android:ui_android_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_base_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "ui_base_unittests",
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "ui_touch_selection_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "ui_touch_selection_unittests",
+        "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "unit_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 2
+        },
+        "test": "unit_tests",
+        "test_id_prefix": "ninja://chrome/test:unit_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "url_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "url_unittests",
+        "test_id_prefix": "ninja://url:url_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "viz_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "viz_unittests",
+        "test_id_prefix": "ninja://components/viz:viz_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_browsertests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "weblayer_browsertests",
+        "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_bundle_test"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "weblayer_bundle_test",
+        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_bundle_test/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "weblayer_instrumentation_test_apk",
+        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_private_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "weblayer_private_instrumentation_test_apk",
+        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_private_instrumentation_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "weblayer_unittests",
+        "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_cts_tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "chromium/android_webview/tools/cts_archive",
+              "location": "android_webview/tools/cts_archive",
+              "revision": "qF6dhyFMW7qFOzHo_Lu-bWxpbe-zRfL1KvHPQtQA3d0C"
+            },
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 2
+        },
+        "test": "webview_cts_tests",
+        "test_id_prefix": "ninja://android_webview/test:webview_cts_tests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_instrumentation_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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",
+          "shards": 7
+        },
+        "test": "webview_instrumentation_test_apk",
+        "test_id_prefix": "ninja://android_webview/test:webview_instrumentation_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_ui_test_app_test_apk"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "webview_ui_test_app_test_apk",
+        "test_id_prefix": "ninja://android_webview/tools/automated_ui_tests:webview_ui_test_app_test_apk/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "wtf_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "wtf_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/"
+      },
+      {
+        "args": [
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "zlib_unittests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4|e2-standard-4",
+              "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": "zlib_unittests",
+        "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/"
+      }
+    ],
+    "scripts": [
+      {
+        "args": [
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
+          "--gtest_also_run_disabled_tests"
+        ],
+        "name": "check_network_annotations",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "script": "check_network_annotations.py",
+        "swarming": {}
+      }
+    ]
+  },
   "android-pie-x86-rel": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json
index 73402f6..7dd0ff69 100644
--- a/testing/buildbot/chromium.dawn.json
+++ b/testing/buildbot/chromium.dawn.json
@@ -329,6 +329,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu --enable-features=Vulkan",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:9bc5-20.0.8",
+              "os": "Ubuntu-18.04.6",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--no-xvfb",
@@ -440,6 +479,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu --enable-features=Vulkan",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:9bc5-20.0.8",
+              "os": "Ubuntu-18.04.6",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -1287,6 +1367,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu --enable-features=Vulkan",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:9bc5-20.0.8",
+              "os": "Ubuntu-18.04.6",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--no-xvfb",
@@ -1398,6 +1517,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu --enable-features=Vulkan",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:9bc5-20.0.8",
+              "os": "Ubuntu-18.04.6",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -2272,6 +2432,48 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "display_attached": "1",
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-12.1",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--platform=mac-mac11",
@@ -2390,6 +2592,50 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "display_attached": "1",
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-12.1",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -4380,6 +4626,48 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "display_attached": "1",
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-12.1",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--platform=mac-mac11",
@@ -4498,6 +4786,50 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "display_attached": "1",
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-12.1",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -5687,6 +6019,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release_x64",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--target=Release_x64",
@@ -5796,6 +6167,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release_x64",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -6625,6 +7037,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release_x64",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--target=Release_x64",
@@ -6734,6 +7185,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release_x64",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -7536,6 +8028,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--git-revision=${got_revision}"
@@ -7643,6 +8174,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
@@ -8439,6 +9011,45 @@
       },
       {
         "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "--flag-specific=webgpu-swiftshader",
           "--initialize-webgpu-adapter-at-startup-timeout-ms=60000",
           "--git-revision=${got_revision}"
@@ -8546,6 +9157,47 @@
           "shards": 2
         },
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "webgpu_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu",
+          "--use-webgpu-adapter=swiftshader",
+          "--test-filter=*web_platform*",
+          "--enable-dawn-backend-validation",
+          "--retry-limit=3",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_swiftshader_web_platform_cts_with_validation_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:5912-26.20.100.8141|8086:3e92-26.20.100.8141",
+              "os": "Windows-10",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 6b01014b..a01b212a 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -67877,7 +67877,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -67929,7 +67929,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -67981,7 +67981,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68033,7 +68033,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68085,7 +68085,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68137,7 +68137,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68189,7 +68189,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68241,7 +68241,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68293,7 +68293,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68345,7 +68345,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68397,7 +68397,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68449,7 +68449,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68501,7 +68501,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68553,7 +68553,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68605,7 +68605,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68658,7 +68658,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68711,7 +68711,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68764,7 +68764,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68817,7 +68817,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68870,7 +68870,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68924,7 +68924,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -68978,7 +68978,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69032,7 +69032,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69086,7 +69086,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69140,7 +69140,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69194,7 +69194,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69248,7 +69248,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69302,7 +69302,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69356,7 +69356,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69410,7 +69410,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69463,7 +69463,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69516,7 +69516,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69569,7 +69569,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69622,7 +69622,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69676,7 +69676,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69730,7 +69730,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69783,7 +69783,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69835,7 +69835,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69887,7 +69887,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69940,7 +69940,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -69993,7 +69993,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70046,7 +70046,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70099,7 +70099,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70151,7 +70151,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70204,7 +70204,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70256,7 +70256,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70309,7 +70309,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70362,7 +70362,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70415,7 +70415,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70468,7 +70468,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70521,7 +70521,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70573,7 +70573,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70625,7 +70625,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70677,7 +70677,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70729,7 +70729,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70782,7 +70782,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70835,7 +70835,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70888,7 +70888,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70940,7 +70940,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -70992,7 +70992,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71044,7 +71044,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71096,7 +71096,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71148,7 +71148,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71200,7 +71200,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71252,7 +71252,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71304,7 +71304,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71356,7 +71356,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71408,7 +71408,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71460,7 +71460,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71512,7 +71512,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71564,7 +71564,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71616,7 +71616,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71668,7 +71668,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71720,7 +71720,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71772,7 +71772,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71824,7 +71824,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71876,7 +71876,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12"
             }
           ],
@@ -71937,7 +71937,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -71991,7 +71991,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72045,7 +72045,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72099,7 +72099,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72153,7 +72153,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72207,7 +72207,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72261,7 +72261,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72315,7 +72315,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72369,7 +72369,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72423,7 +72423,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72477,7 +72477,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72531,7 +72531,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72585,7 +72585,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72639,7 +72639,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72693,7 +72693,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72747,7 +72747,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72801,7 +72801,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72855,7 +72855,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72909,7 +72909,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -72963,7 +72963,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73017,7 +73017,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73071,7 +73071,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73125,7 +73125,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73179,7 +73179,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73233,7 +73233,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73287,7 +73287,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73341,7 +73341,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73395,7 +73395,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73449,7 +73449,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73503,7 +73503,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73558,7 +73558,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73613,7 +73613,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73668,7 +73668,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73723,7 +73723,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73778,7 +73778,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73833,7 +73833,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73888,7 +73888,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73943,7 +73943,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -73998,7 +73998,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74053,7 +74053,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74109,7 +74109,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74165,7 +74165,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74221,7 +74221,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74277,7 +74277,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74333,7 +74333,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74389,7 +74389,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74445,7 +74445,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74501,7 +74501,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74557,7 +74557,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74613,7 +74613,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74669,7 +74669,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74725,7 +74725,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74781,7 +74781,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74837,7 +74837,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74893,7 +74893,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -74949,7 +74949,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75005,7 +75005,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75061,7 +75061,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75117,7 +75117,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75173,7 +75173,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75229,7 +75229,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75285,7 +75285,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75341,7 +75341,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75397,7 +75397,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75453,7 +75453,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75509,7 +75509,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75565,7 +75565,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75620,7 +75620,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75675,7 +75675,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75730,7 +75730,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75785,7 +75785,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75840,7 +75840,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75895,7 +75895,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -75950,7 +75950,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76005,7 +76005,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76060,7 +76060,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76116,7 +76116,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76172,7 +76172,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76228,7 +76228,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76284,7 +76284,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76340,7 +76340,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76396,7 +76396,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76452,7 +76452,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76508,7 +76508,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76563,7 +76563,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76617,7 +76617,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76671,7 +76671,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76725,7 +76725,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76780,7 +76780,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76835,7 +76835,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76890,7 +76890,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -76945,7 +76945,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77000,7 +77000,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77055,7 +77055,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77110,7 +77110,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77165,7 +77165,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77220,7 +77220,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77274,7 +77274,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77328,7 +77328,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77382,7 +77382,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77437,7 +77437,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77492,7 +77492,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77547,7 +77547,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77601,7 +77601,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77656,7 +77656,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77711,7 +77711,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77766,7 +77766,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77820,7 +77820,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77874,7 +77874,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77929,7 +77929,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -77984,7 +77984,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78039,7 +78039,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78094,7 +78094,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78149,7 +78149,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78204,7 +78204,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78259,7 +78259,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78314,7 +78314,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78369,7 +78369,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78423,7 +78423,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78477,7 +78477,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78531,7 +78531,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78585,7 +78585,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78639,7 +78639,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78693,7 +78693,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78747,7 +78747,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78802,7 +78802,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78857,7 +78857,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78912,7 +78912,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -78967,7 +78967,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79022,7 +79022,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79077,7 +79077,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79132,7 +79132,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79187,7 +79187,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79242,7 +79242,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79296,7 +79296,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79350,7 +79350,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79404,7 +79404,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79458,7 +79458,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79512,7 +79512,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79566,7 +79566,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79620,7 +79620,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79674,7 +79674,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79728,7 +79728,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79782,7 +79782,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79836,7 +79836,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79890,7 +79890,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79944,7 +79944,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -79998,7 +79998,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80052,7 +80052,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80106,7 +80106,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80160,7 +80160,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80214,7 +80214,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80268,7 +80268,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80322,7 +80322,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80376,7 +80376,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80430,7 +80430,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80484,7 +80484,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80538,7 +80538,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80592,7 +80592,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80646,7 +80646,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80700,7 +80700,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80754,7 +80754,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80808,7 +80808,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80862,7 +80862,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80916,7 +80916,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
@@ -80970,7 +80970,7 @@
           ],
           "dimension_sets": [
             {
-              "cpu": "arm64",
+              "cpu": "x86-64",
               "os": "Mac-12.4"
             }
           ],
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 9d1ac676..4b17d1d 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -2414,6 +2414,41 @@
       },
     },
 
+    # Test suites to run the CTS with validation layers only on CI for
+    # configurations where capacity is constrained.
+    'gpu_dawn_telemetry_cts_tests_with_ci_only_validation': {
+      'webgpu_cts_with_validation': {
+        'ci_only': True,
+        'args': [
+          '--enable-dawn-backend-validation',
+        ],
+        'mixins': [
+          'has_native_resultdb_integration',
+          'webgpu_telemetry_cts',
+        ],
+        'swarming': {
+          'shards': 14,
+        },
+        'telemetry_test_name': 'webgpu_cts',
+      },
+      'webgpu_swiftshader_web_platform_cts_with_validation': {
+        'ci_only': True,
+        'args': [
+          '--use-webgpu-adapter=swiftshader',
+          '--test-filter=*web_platform*',
+          '--enable-dawn-backend-validation',
+        ],
+        'mixins': [
+          'has_native_resultdb_integration',
+          'webgpu_telemetry_cts',
+        ],
+        'swarming': {
+          'shards': 2,
+        },
+        'telemetry_test_name': 'webgpu_cts',
+      },
+    },
+
     'gpu_dawn_telemetry_cts_tests_with_validation': {
       'webgpu_cts_with_validation': {
         'args': [
@@ -5802,8 +5837,9 @@
       'gpu_webgpu_integration_partial_backend_validation_isolated_scripts',
     ],
 
-    'gpu_dawn_telemetry_cts_regular': [
+    'gpu_dawn_telemetry_cts_regular_and_ci_only_validation': [
       'gpu_dawn_telemetry_cts_tests',
+      'gpu_dawn_telemetry_cts_tests_with_ci_only_validation',
     ],
 
     'gpu_dawn_telemetry_cts_regular_and_validation': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 84552d05..75537ac 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -1050,6 +1050,24 @@
         'use_swarming': True,
         'os_type': 'android',
       },
+      # A builder for early prototype of test-reviver in Clank.
+      # TODO(crbug.com/1348392): Remove this builder once we have a way to reuse
+      # the built binaries or a formal solution for test-reviver.
+      'android-pie-x86-fyi-rel-reviver': {
+        'mixins': [
+          'has_native_resultdb_integration',
+          'pie-x86-emulator',
+          'emulator-4-cores',
+          'linux-bionic',
+          'x86-64',
+          'gtest_run_disabled',
+        ],
+        'os_type': 'android',
+        'test_suites': {
+          'gtest_tests': 'android_pie_rel_emulator_gtests',
+          'scripts': 'chromium_android_scripts',
+        }
+      },
       'android-pie-x86-rel': {
         'mixins': [
           'has_native_resultdb_integration',
@@ -2169,7 +2187,7 @@
           'linux_intel_uhd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2193,7 +2211,7 @@
           'linux_intel_uhd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2219,7 +2237,7 @@
           'mac_retina_amd_gpu_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2272,7 +2290,7 @@
           'mac_retina_amd_gpu_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2311,7 +2329,7 @@
           'win10_intel_hd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough_win_intel',
           'isolated_scripts': 'gpu_dawn_isolated_scripts_win',
         },
@@ -2335,7 +2353,7 @@
           'win10_intel_hd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough_win_intel',
           'isolated_scripts': 'gpu_dawn_isolated_scripts_win',
         },
@@ -2361,7 +2379,7 @@
           'win10_intel_hd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough_win_intel',
           'isolated_scripts': 'gpu_dawn_isolated_scripts_win',
         },
@@ -2385,7 +2403,7 @@
           'win10_intel_hd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular',
+          'gpu_telemetry_tests': 'gpu_dawn_telemetry_cts_regular_and_ci_only_validation',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough_win_intel',
           'isolated_scripts': 'gpu_dawn_isolated_scripts_win',
         },
@@ -3412,7 +3430,7 @@
         ],
         'mixins': [
           'has_native_resultdb_integration',
-          'mac_12_arm64',
+          'mac_12_x64',
           'mac_toolchain',
           'out_dir_arg',
           'xcode_14_beta',
@@ -3430,7 +3448,7 @@
         ],
         'mixins': [
           'has_native_resultdb_integration',
-          'mac_beta_arm64',
+          'mac_beta_x64',
           'mac_toolchain',
           'out_dir_arg',
           'xcode_14_beta',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 3a760127..d341ba20 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3423,17 +3423,12 @@
                 {
                     "name": "RecipeTasksRuleBasedDiscountDriveManagedUsersCartOptimizeRecipeTasksSAPIV2Fre_Enabled",
                     "params": {
-                        "NtpChromeCartModuleAbandonedCartDiscountParam": "true",
-                        "NtpChromeCartModuleAbandonedCartDiscountUseUtmParam": "true",
-                        "NtpChromeCartModuleHeuristicsImprovementParam": "true",
                         "NtpDriveModuleExperimentGroupParam": "foo:bar",
                         "NtpDriveModuleManagedUsersOnlyParam": "true",
                         "NtpModulesLoadTimeoutMillisecondsParam": "3000",
-                        "discount-fetch-delay": "1h",
                         "use_sapi_v2": "true"
                     },
                     "enable_features": [
-                        "NtpChromeCartModule",
                         "NtpDriveModule",
                         "NtpModulesLoadTimeoutMilliseconds",
                         "NtpPhotosModule"
@@ -3445,17 +3440,12 @@
                 {
                     "name": "Recipes_SAPIV2_20220415",
                     "params": {
-                        "NtpChromeCartModuleAbandonedCartDiscountParam": "true",
-                        "NtpChromeCartModuleAbandonedCartDiscountUseUtmParam": "true",
-                        "NtpChromeCartModuleHeuristicsImprovementParam": "true",
                         "NtpDriveModuleExperimentGroupParam": "foo:bar",
                         "NtpDriveModuleManagedUsersOnlyParam": "true",
                         "NtpModulesLoadTimeoutMillisecondsParam": "3000",
-                        "discount-fetch-delay": "1h",
                         "use_sapi_v2": "true"
                     },
                     "enable_features": [
-                        "NtpChromeCartModule",
                         "NtpDriveModule",
                         "NtpModulesLoadTimeoutMilliseconds",
                         "NtpRecipeTasksModule"
@@ -3467,16 +3457,11 @@
                 {
                     "name": "Recipes_SAPIV2_Control_20220415",
                     "params": {
-                        "NtpChromeCartModuleAbandonedCartDiscountParam": "true",
-                        "NtpChromeCartModuleAbandonedCartDiscountUseUtmParam": "true",
-                        "NtpChromeCartModuleHeuristicsImprovementParam": "true",
                         "NtpDriveModuleExperimentGroupParam": "foo:bar",
                         "NtpDriveModuleManagedUsersOnlyParam": "true",
-                        "NtpModulesLoadTimeoutMillisecondsParam": "3000",
-                        "discount-fetch-delay": "1h"
+                        "NtpModulesLoadTimeoutMillisecondsParam": "3000"
                     },
                     "enable_features": [
-                        "NtpChromeCartModule",
                         "NtpDriveModule",
                         "NtpModulesLoadTimeoutMilliseconds",
                         "NtpRecipeTasksModule"
@@ -6806,6 +6791,24 @@
             ]
         }
     ],
+    "PartialCustomTabs3rdPartyPolicy": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "default_policy": "use-denylist"
+                    },
+                    "enable_features": [
+                        "CCTResizableForThirdParties"
+                    ]
+                }
+            ]
+        }
+    ],
     "PartitionAllocBackupRefPtr": [
         {
             "platforms": [
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index a910d7b..993bc29 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -36,7 +36,6 @@
       !data.ReadTextTrackFontStyle(&out->text_track_font_style) ||
       !data.ReadTextTrackFontVariant(&out->text_track_font_variant) ||
       !data.ReadTextTrackWindowColor(&out->text_track_window_color) ||
-      !data.ReadTextTrackWindowPadding(&out->text_track_window_padding) ||
       !data.ReadTextTrackWindowRadius(&out->text_track_window_radius) ||
       !data.ReadPrimaryPointerType(&out->primary_pointer_type) ||
       !data.ReadPrimaryHoverType(&out->primary_hover_type) ||
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 800333b4..d7f0821 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -122,7 +122,6 @@
 source_set("blink_headers") {
   sources = [
     "platform/audio/web_audio_device_source_type.h",
-    "platform/blame_context.h",
     "platform/child_url_loader_factory_bundle.h",
     "platform/cross_variant_mojo_util.h",
     "platform/file_path_conversion.h",
diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h
index 33ca0140..f41b2ac 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -195,8 +195,6 @@
   // around WebVTT text tracks.
   // Window color can be any legal CSS color descriptor.
   std::string text_track_window_color;
-  // Window padding is in em.
-  std::string text_track_window_padding;
   // Window radius is in pixels.
   std::string text_track_window_radius;
 
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
index d4c86ca..74de926 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -496,11 +496,6 @@
     return r.text_track_window_color;
   }
 
-  static const std::string& text_track_window_padding(
-      const blink::web_pref::WebPreferences& r) {
-    return r.text_track_window_padding;
-  }
-
   static const std::string& text_track_window_radius(
       const blink::web_pref::WebPreferences& r) {
     return r.text_track_window_radius;
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
index 4638c6cf..b1976c6 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -246,8 +246,6 @@
   // around WebVTT text tracks.
   // Window color can be any legal CSS color descriptor.
   string text_track_window_color;
-  // Window padding is in em.
-  string text_track_window_padding;
   // Window radius is in pixels.
   string text_track_window_radius;
 
diff --git a/third_party/blink/public/platform/blame_context.h b/third_party/blink/public/platform/blame_context.h
deleted file mode 100644
index b86670b..0000000
--- a/third_party/blink/public/platform/blame_context.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_BLAME_CONTEXT_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_BLAME_CONTEXT_H_
-
-#include "base/trace_event/blame_context.h"
-
-namespace blink {
-
-using BlameContext = base::trace_event::BlameContext;
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_BLAME_CONTEXT_H_
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 0655dca..bc4f144b 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -66,10 +66,6 @@
 
 namespace base {
 class SingleThreadTaskRunner;
-
-namespace trace_event {
-class BlameContext;
-}  // namespace trace_event
 }  // namespace base
 
 namespace gfx {
@@ -134,7 +130,6 @@
 class WebURLLoaderFactory;
 class WebVideoCaptureImplManager;
 struct WebContentSecurityPolicyHeader;
-using BlameContext = base::trace_event::BlameContext;
 
 namespace scheduler {
 class WebThreadScheduler;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 014a378..8b2a4fcb 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -59,7 +59,6 @@
 #include "third_party/blink/public/mojom/loader/same_document_navigation_type.mojom-shared.h"
 #include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom-shared.h"
 #include "third_party/blink/public/mojom/portal/portal.mojom-shared.h"
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/public/platform/cross_variant_mojo_util.h"
 #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
 #include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h
index ee890fb..32b14511 100644
--- a/third_party/blink/public/web/web_settings.h
+++ b/third_party/blink/public/web/web_settings.h
@@ -233,7 +233,6 @@
   virtual void SetTextTrackTextShadow(const WebString&) = 0;
   virtual void SetTextTrackTextSize(const WebString&) = 0;
   virtual void SetTextTrackWindowColor(const WebString&) = 0;
-  virtual void SetTextTrackWindowPadding(const WebString&) = 0;
   virtual void SetTextTrackWindowRadius(const WebString&) = 0;
   virtual void SetThreadedScrollingEnabled(bool) = 0;
   virtual void SetTouchDragDropEnabled(bool) = 0;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_cache_consumer.cc b/third_party/blink/renderer/bindings/core/v8/script_cache_consumer.cc
index b5aad95a..126a8f5 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_cache_consumer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_cache_consumer.cc
@@ -214,8 +214,8 @@
   // Clear the task runner, we don't need it anymore since we've already made
   // our way to the main thread.
   finish_callback_task_runner_.reset();
-  client->NotifyCacheConsumeFinished();
   AdvanceState(State::kCalledFinishCallbackBit);
+  client->NotifyCacheConsumeFinished();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
index f378caa..bdfad247 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -32,7 +32,6 @@
 
 #include <algorithm>
 
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
diff --git a/third_party/blink/renderer/core/animation/view_timeline.cc b/third_party/blink/renderer/core/animation/view_timeline.cc
index 13d12d64..52ea88f 100644
--- a/third_party/blink/renderer/core/animation/view_timeline.cc
+++ b/third_party/blink/renderer/core/animation/view_timeline.cc
@@ -62,9 +62,6 @@
 absl::optional<ScrollTimeline::ScrollOffsets> ViewTimeline::CalculateOffsets(
     PaintLayerScrollableArea* scrollable_area,
     ScrollOrientation physical_orientation) const {
-  ScrollOffset scroll_dimensions = scrollable_area->MaximumScrollOffset() -
-                                   scrollable_area->MinimumScrollOffset();
-
   DCHECK(subject());
   LayoutBox* layout_box = subject()->GetLayoutBox();
   DCHECK(layout_box);
@@ -77,22 +74,16 @@
       ComputeOffset(layout_box, source_layout, physical_orientation);
   double target_size = 0;
   double viewport_size = 0;
-  double max_offset = 0;
   if (physical_orientation == kHorizontalScroll) {
     target_size = layout_box->Size().Width().ToDouble();
     viewport_size = scrollable_area->VisibleScrollSnapportRect().Width();
-    max_offset = scroll_dimensions.x();
   } else {
     target_size = layout_box->Size().Height().ToDouble();
     viewport_size = scrollable_area->VisibleScrollSnapportRect().Height();
-    max_offset = scroll_dimensions.y();
   }
 
-  // Clamping the offsets to the scrollable range. It is unclear if this is the
-  // desired behavior as it also makes sense not to clamp.
-  // TODO(crbug.com/1329159): Revisit once clarified in the spec.
-  double start_offset = std::max<double>(target_offset - viewport_size, 0);
-  double end_offset = std::min<double>(target_offset + target_size, max_offset);
+  double start_offset = target_offset - viewport_size;
+  double end_offset = target_offset + target_size;
   return absl::make_optional<ScrollOffsets>(start_offset, end_offset);
 }
 
diff --git a/third_party/blink/renderer/core/aom/accessible_node.cc b/third_party/blink/renderer/core/aom/accessible_node.cc
index cac140fa92..87861e5 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.cc
+++ b/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -198,10 +198,14 @@
 }
 
 Document* AccessibleNode::GetDocument() const {
-  if (document_)
+  if (document_) {
+    DCHECK(!element_);
     return document_;
-  if (element_)
+  }
+  if (element_) {
+    DCHECK(!document_);
     return &element_->GetDocument();
+  }
 
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/aom/accessible_node.h b/third_party/blink/renderer/core/aom/accessible_node.h
index e6bb38873..1e719a4b 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.h
+++ b/third_party/blink/renderer/core/aom/accessible_node.h
@@ -397,7 +397,7 @@
       relation_list_properties_;
 
   // This object's owner Element, if it corresponds to an Element.
-  Member<Element> element_;
+  const Member<Element> element_;
 
   // The object's owner Document. Only set if |element_| is nullptr.
   Member<Document> document_;
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
index 41b4e42..3efc273 100644
--- a/third_party/blink/renderer/core/css/css_default_style_sheets.cc
+++ b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -297,8 +297,6 @@
       builder.Append("video::-webkit-media-text-track-display { ");
       AddTextTrackCSSProperties(&builder, CSSPropertyID::kBackgroundColor,
                                 settings->GetTextTrackWindowColor());
-      AddTextTrackCSSProperties(&builder, CSSPropertyID::kPadding,
-                                settings->GetTextTrackWindowPadding());
       AddTextTrackCSSProperties(&builder, CSSPropertyID::kBorderRadius,
                                 settings->GetTextTrackWindowRadius());
       builder.Append(" } video::cue { ");
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
index 00e747c..36139d2c 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
 
 #include <unicode/utf16.h>
+#include "build/build_config.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -299,7 +300,8 @@
     return;
 
   while (node_ && (node_ != past_end_node_ || shadow_depth_)) {
-#if DCHECK_IS_ON()
+    // TODO(crbug.com/1296290): Disable this DCHECK as it's troubling CrOS engs.
+#if DCHECK_IS_ON() && !BUILDFLAG(IS_CHROMEOS)
     // |node_| shouldn't be after |past_end_node_|.
     if (past_end_node_) {
       DCHECK_LE(PositionTemplate<Strategy>(node_, 0),
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc
index d67f8d0..4ede738 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -380,10 +380,6 @@
   settings_->SetTextTrackWindowColor(color);
 }
 
-void WebSettingsImpl::SetTextTrackWindowPadding(const WebString& padding) {
-  settings_->SetTextTrackWindowPadding(padding);
-}
-
 void WebSettingsImpl::SetTextTrackWindowRadius(const WebString& radius) {
   settings_->SetTextTrackWindowRadius(radius);
 }
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h
index 14cec5a..dded9b33 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.h
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -175,7 +175,6 @@
   void SetTextTrackTextShadow(const WebString&) override;
   void SetTextTrackTextSize(const WebString&) override;
   void SetTextTrackWindowColor(const WebString&) override;
-  void SetTextTrackWindowPadding(const WebString&) override;
   void SetTextTrackWindowRadius(const WebString&) override;
   void SetThreadedScrollingEnabled(bool) override;
   void SetTouchDragDropEnabled(bool) override;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 04f247a..f50f395 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1616,8 +1616,6 @@
   settings->SetTextTrackMarginPercentage(prefs.text_track_margin_percentage);
   settings->SetTextTrackWindowColor(
       WebString::FromASCII(prefs.text_track_window_color));
-  settings->SetTextTrackWindowPadding(
-      WebString::FromASCII(prefs.text_track_window_padding));
   settings->SetTextTrackWindowRadius(
       WebString::FromASCII(prefs.text_track_window_radius));
 
diff --git a/third_party/blink/renderer/core/frame/frame_client.h b/third_party/blink/renderer/core/frame/frame_client.h
index 216a8681..5ffa8a5 100644
--- a/third_party/blink/renderer/core/frame/frame_client.h
+++ b/third_party/blink/renderer/core/frame/frame_client.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_CLIENT_H_
 
 #include "base/unguessable_token.h"
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index dd19180..133797e 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1507,7 +1507,6 @@
             inheriting_agent_factory),
       frame_scheduler_(page.GetPageScheduler()->CreateFrameScheduler(
           this,
-          nullptr,
           /*TODO(crbug.com/1170350): Set for portals*/ IsInFencedFrameTree(),
           IsMainFrame() ? FrameScheduler::FrameType::kMainFrame
                         : FrameScheduler::FrameType::kSubframe)),
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5
index ad66057..57803c5 100644
--- a/third_party/blink/renderer/core/frame/settings.json5
+++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -773,10 +773,6 @@
       type: "String",
     },
     {
-      name: "textTrackWindowPadding",
-      type: "String",
-    },
-    {
       name: "textTrackWindowRadius",
       type: "String",
     },
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 4dde00b1..1fe7f09 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -472,6 +472,9 @@
   context_->SetItemIndex(line_info->ItemsData().items,
                          line_info->EndItemIndex());
 
+  if (line_info->UseFirstLineStyle())
+    container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
+
   // Even if we have something in-flow, it may just be empty items that
   // shouldn't trigger creation of a line. Exit now if that's the case.
   if (line_info->IsEmptyLine())
@@ -497,8 +500,6 @@
   if (LIKELY(!Node().IsSvgText() && !Node().IsTextCombine()))
     line_box->MoveInBlockDirection(line_box_metrics.ascent);
 
-  if (line_info->UseFirstLineStyle())
-    container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
   if (UNLIKELY(Node().IsTextCombine())) {
     // The effective size of combined text is 1em square[1]
     // [1] https://drafts.csswg.org/css-writing-modes-3/#text-combine-layout
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index 14ccc9f..d387a63 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -65,6 +65,31 @@
   EXPECT_TRUE(empty.Current()->LineBoxFragment()->IsEmptyLineBox());
 }
 
+TEST_F(NGInlineLayoutAlgorithmTest, TypesForFirstLine) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+    div::first-line { font-size: 2em; }
+    </style>
+    <div id="normal">normal</div>
+    <div id="empty"><span></span></div>
+  )HTML");
+  NGInlineCursor normal(
+      *To<LayoutBlockFlow>(GetLayoutObjectByElementId("normal")));
+  normal.MoveToFirstLine();
+  EXPECT_FALSE(normal.Current()->LineBoxFragment()->IsEmptyLineBox());
+  EXPECT_EQ(normal.Current().StyleVariant(), NGStyleVariant::kFirstLine);
+  EXPECT_EQ(normal.Current()->LineBoxFragment()->StyleVariant(),
+            NGStyleVariant::kFirstLine);
+
+  NGInlineCursor empty(
+      *To<LayoutBlockFlow>(GetLayoutObjectByElementId("empty")));
+  empty.MoveToFirstLine();
+  EXPECT_TRUE(empty.Current()->LineBoxFragment()->IsEmptyLineBox());
+  EXPECT_EQ(empty.Current().StyleVariant(), NGStyleVariant::kFirstLine);
+  EXPECT_EQ(empty.Current()->LineBoxFragment()->StyleVariant(),
+            NGStyleVariant::kFirstLine);
+}
+
 TEST_F(NGInlineLayoutAlgorithmTest, TypesForBlockInInline) {
   ScopedLayoutNGBlockInInlineForTest block_in_inline_scope(true);
   SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index bcd96cf..a33cc40 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -897,13 +897,6 @@
     if (AXObject* parent = cache.Get(parent_accessible_node))
       return parent;
 
-    // If |accessible_node|'s parent is attached to a DOM element, we return the
-    // AXObject of the DOM element as the parent AXObject of |accessible_node|,
-    // since the accessible node directly attached to an element should not have
-    // its own AXObject.
-    if (Element* element = parent_accessible_node->element())
-      return cache.GetOrCreate(element);
-
     // Compute grandparent first, since constructing parent AXObject for
     // |accessible_node| requires grandparent to be provided.
     AXObject* grandparent_object =
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index a0b5086..712abe8 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -821,6 +821,17 @@
   if (!node)
     return nullptr;
 
+#if DCHECK_IS_ON()
+  if (const Element* element = DynamicTo<Element>(node)) {
+    if (AccessibleNode* accessible_node = element->ExistingAccessibleNode()) {
+      DCHECK(!accessible_node_mapping_.Contains(accessible_node))
+          << "The accessible node directly attached to an element should not "
+             "have its own AXObject: "
+          << element;
+    }
+  }
+#endif
+
   LayoutObject* layout_object = node->GetLayoutObject();
 
   AXID layout_id = 0;
@@ -875,6 +886,17 @@
   if (has_been_disposed_)
     return SafeGet(node);
 
+#if DCHECK_IS_ON()
+  if (const Element* element = DynamicTo<Element>(node)) {
+    if (AccessibleNode* accessible_node = element->ExistingAccessibleNode()) {
+      DCHECK(!accessible_node_mapping_.Contains(accessible_node))
+          << "The accessible node directly attached to an element should not "
+             "have its own AXObject: "
+          << element;
+    }
+  }
+#endif
+
   LayoutObject* layout_object = node->GetLayoutObject();
 
   AXID layout_id = 0;
@@ -1008,6 +1030,16 @@
   if (!accessible_node)
     return nullptr;
 
+  if (accessible_node->element()) {
+    DCHECK(!accessible_node_mapping_.Contains(accessible_node))
+        << "The accessible node directly attached to an element should not "
+           "have its own AXObject: "
+        << accessible_node->element();
+    // When the AccessibleNode is attached to an element, return the element's
+    // accessible object instead.
+    return SafeGet(accessible_node->element());
+  }
+
   auto it_ax = accessible_node_mapping_.find(accessible_node);
   AXID ax_id = it_ax != accessible_node_mapping_.end() ? it_ax->value : 0;
   DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id));
@@ -1018,7 +1050,7 @@
   AXObject* result = it_result != objects_.end() ? it_result->value : nullptr;
 #if DCHECK_IS_ON()
   DCHECK(result) << "Had AXID for accessible_node but no entry in objects_";
-  DCHECK(result->IsVirtualObject());
+  DCHECK(IsA<AXVirtualObject>(result));
   // Do not allow detached objects except when disposing entire tree.
   DCHECK(!result->IsDetached() || has_been_disposed_)
       << "Detached AXVirtualObject in map: "
@@ -1271,6 +1303,12 @@
       << "A virtual object must have a parent, and cannot exist without one. "
          "The parent is set when the object is constructed.";
 
+  DCHECK(!accessible_node->element())
+      << "The accessible node directly attached to an element should not "
+         "have its own AXObject, since the AXObject will be keyed off of the "
+         "element instead: "
+      << accessible_node->element();
+
   if (!parent->CanHaveChildren())
     return nullptr;
 
@@ -2279,7 +2317,8 @@
 }
 
 void AXObjectCacheImpl::ChildrenChanged(Node* node) {
-  ChildrenChanged(Get(node));
+  // Use SafeGet() because there is no guarantee that layout is clean right now.
+  ChildrenChanged(SafeGet(node));
 }
 
 // ChildrenChanged gets called a lot. For the accessibility tests that
@@ -2313,6 +2352,7 @@
 }
 
 void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) {
+  DCHECK(accessible_node);
   ChildrenChanged(Get(accessible_node));
 }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 7a6795d4..6d58e9f 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -229,6 +229,8 @@
 
   AXID GetExistingAXID(Node*) override;
 
+  // Return an AXObject for the AccessibleNode. If the AccessibleNode is
+  // attached to an element, will return the AXObject for that element instead.
   AXObject* Get(AccessibleNode*);
   AXObject* Get(AbstractInlineTextBox*);
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
index 958e2e9c..0b09483 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
@@ -14,7 +14,14 @@
                                  AccessibleNode* accessible_node)
     : AXObject(axObjectCache),
       accessible_node_(accessible_node),
-      aria_role_(ax::mojom::blink::Role::kUnknown) {}
+      aria_role_(ax::mojom::blink::Role::kUnknown) {
+  DCHECK(accessible_node_);
+  DCHECK(!accessible_node_->element())
+      << "The accessible node directly attached to an element should not "
+         "have its own AXObject, since the AXObject will be keyed off of "
+         "the element instead: "
+      << accessible_node_->element();
+}
 
 AXVirtualObject::~AXVirtualObject() = default;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
index 12b4ec7..2560f84 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h
@@ -48,6 +48,13 @@
   ax::mojom::blink::Role aria_role_;
 };
 
+template <>
+struct DowncastTraits<AXVirtualObject> {
+  static bool AllowFrom(const AXObject& object) {
+    return object.IsVirtualObject();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_VIRTUAL_OBJECT_H_
diff --git a/third_party/blink/renderer/modules/locks/lock_manager.cc b/third_party/blink/renderer/modules/locks/lock_manager.cc
index e646d156..807fdc5 100644
--- a/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -535,14 +535,19 @@
     ScriptPromiseResolver* resolver,
     base::OnceCallback<void()> callback,
     bool allow_access) {
-  cached_allowed_ = allow_access;
+  if (cached_allowed_.has_value()) {
+    DCHECK_EQ(cached_allowed_.value(), allow_access);
+  } else {
+    cached_allowed_ = allow_access;
+  }
+
   ScriptState* script_state = resolver->GetScriptState();
 
   if (!script_state->ContextIsValid()) {
     return;
   }
 
-  if (allow_access) {
+  if (cached_allowed_.value()) {
     std::move(callback).Run();
     return;
   }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_node.cc b/third_party/blink/renderer/modules/webaudio/audio_node.cc
index 778ac59..9c5c98a 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/modules/webaudio/audio_node.h"
 
+#include <inttypes.h>
+
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_node_options.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h"
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
index ace8065..03d9adc 100644
--- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc
@@ -25,6 +25,8 @@
 
 #include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
 
+#include <inttypes.h>
+
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_source_options.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_context.h"
diff --git a/third_party/blink/renderer/platform/DEPS b/third_party/blink/renderer/platform/DEPS
index 9594028..09cc275c 100644
--- a/third_party/blink/renderer/platform/DEPS
+++ b/third_party/blink/renderer/platform/DEPS
@@ -47,6 +47,7 @@
     "+base/synchronization/waitable_event.h",
     "+base/android/sys_utils.h",
     "+base/system/sys_info.h",
+    "+base/task/common/lazy_now.h",
     "+base/task/delayed_task_handle.h",
     "+base/task/sequence_manager/task_time_observer.h",
     "+base/test",
diff --git a/third_party/blink/renderer/platform/fonts/font_test.cc b/third_party/blink/renderer/platform/fonts/font_test.cc
index 54dddfc0..79700b94 100644
--- a/third_party/blink/renderer/platform/fonts/font_test.cc
+++ b/third_party/blink/renderer/platform/fonts/font_test.cc
@@ -102,7 +102,10 @@
       blink::test::BlinkWebTestsFontsTestDataPath("mplus-1p-regular.woff"), 16);
   const SimpleFontData* font_data = font.PrimaryFont();
   ASSERT_TRUE(font_data);
-  EXPECT_FALSE(font_data->GetFontMetrics().IdeographicFullWidth().has_value());
+  // If the `vmtx` table is missing, the vertical advance should be synthesized.
+  ASSERT_TRUE(font_data->GetFontMetrics().IdeographicFullWidth().has_value());
+  EXPECT_EQ(*font_data->GetFontMetrics().IdeographicFullWidth(),
+            font_data->GetFontMetrics().Height());
 }
 
 // A Japanese font, with the "water" glyph, with the `vmtx` table.
diff --git a/third_party/blink/renderer/platform/fonts/simple_font_data.cc b/third_party/blink/renderer/platform/fonts/simple_font_data.cc
index 5e0cc2d..7fbce91 100644
--- a/third_party/blink/renderer/platform/fonts/simple_font_data.cc
+++ b/third_party/blink/renderer/platform/fonts/simple_font_data.cc
@@ -179,13 +179,15 @@
 }
 
 void SimpleFontData::PlatformGlyphInit() {
+  // Widths in |font_metrics_| should be initial values.
+  DCHECK(!font_metrics_.IdeographicFullWidth());
   const FontPlatformData& platform_data = PlatformData();
   SkTypeface* typeface = platform_data.Typeface();
+
   if (!typeface->countGlyphs()) {
     space_glyph_ = 0;
     space_width_ = 0;
     zero_glyph_ = 0;
-    font_metrics_.SetIdeographicFullWidth(absl::nullopt);
     return;
   }
 
@@ -216,17 +218,15 @@
 
   if (cjk_water_glyph)
     font_metrics_.SetIdeographicFullWidth(WidthForGlyph(cjk_water_glyph));
-  else
-    font_metrics_.SetIdeographicFullWidth(absl::nullopt);
 }
 
 void SimpleFontData::PlatformGlyphInitVerticalUpright(Glyph cjk_water_glyph) {
   DCHECK_EQ(PlatformData().Orientation(), FontOrientation::kVerticalUpright);
+  // Widths in |font_metrics_| should be initial values.
+  DCHECK(!font_metrics_.IdeographicFullWidth());
 
-  if (!cjk_water_glyph) {
-    font_metrics_.SetIdeographicFullWidth(absl::nullopt);
+  if (!cjk_water_glyph)
     return;
-  }
 
   // The vertical metrics is available only in |HarfBuzzFontData|, but it can't
   // be constructed while initializing |SimpleFontData|. See crbug.com/784389.
@@ -238,16 +238,10 @@
       platform_data.GetHarfBuzzFace()->UnitsPerEmFromHeadTable();
   const float size_per_unit =
       platform_data.size() / (units_per_em ? units_per_em : 1);
-  // Use a value for |height_fallback| that can detect the "fallback" case.
-  constexpr int height_fallback = 0;
   vertical_data->SetScaleAndFallbackMetrics(
-      size_per_unit, metrics.FloatAscent(), height_fallback);
-  const float cjk_water_height = vertical_data->AdvanceHeight(cjk_water_glyph);
-  if (cjk_water_height == height_fallback) {
-    font_metrics_.SetIdeographicFullWidth(absl::nullopt);
-    return;
-  }
-  font_metrics_.SetIdeographicFullWidth(cjk_water_height);
+      size_per_unit, metrics.FloatAscent(), metrics.Height());
+  font_metrics_.SetIdeographicFullWidth(
+      vertical_data->AdvanceHeight(cjk_water_glyph));
 }
 
 const SimpleFontData* SimpleFontData::FontDataForCharacter(UChar32) const {
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit.h b/third_party/blink/renderer/platform/geometry/layout_unit.h
index cb2b89e..54623b8a 100644
--- a/third_party/blink/renderer/platform/geometry/layout_unit.h
+++ b/third_party/blink/renderer/platform/geometry/layout_unit.h
@@ -107,6 +107,8 @@
   }
   constexpr explicit LayoutUnit(uint64_t value)
       : value_(base::saturated_cast<int>(value * kFixedPointDenominator)) {}
+  // A |value| is clamped by Min() and Max().
+  // A NaN |value| produces LayoutUnit(0).
   constexpr explicit LayoutUnit(float value)
       : value_(base::saturated_cast<int>(value * kFixedPointDenominator)) {}
   constexpr explicit LayoutUnit(double value)
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
index a75822e91..8c70a0ca 100644
--- a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
+++ b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
@@ -110,6 +110,16 @@
   EXPECT_NEAR(LayoutUnit(345634.12335f).ToFloat(), 345634.12335f, kTolerance);
   EXPECT_NEAR(LayoutUnit(-345634.12335f).ToFloat(), -345634.12335f, kTolerance);
   EXPECT_NEAR(LayoutUnit(-345634).ToFloat(), -345634.0f, kTolerance);
+
+  using Limits = std::numeric_limits<float>;
+  // Larger than Max()
+  EXPECT_EQ(LayoutUnit::Max(), LayoutUnit(Limits::max()));
+  EXPECT_EQ(LayoutUnit::Max(), LayoutUnit(Limits::infinity()));
+  // Smaller than Min()
+  EXPECT_EQ(LayoutUnit::Min(), LayoutUnit(Limits::lowest()));
+  EXPECT_EQ(LayoutUnit::Min(), LayoutUnit(-Limits::infinity()));
+
+  EXPECT_EQ(LayoutUnit(), LayoutUnit::Clamp(Limits::quiet_NaN()));
 }
 
 TEST(LayoutUnitTest, LayoutUnitRounding) {
diff --git a/third_party/blink/renderer/platform/scheduler/DEPS b/third_party/blink/renderer/platform/scheduler/DEPS
index 7bae9b4..f7c27de3 100644
--- a/third_party/blink/renderer/platform/scheduler/DEPS
+++ b/third_party/blink/renderer/platform/scheduler/DEPS
@@ -35,9 +35,9 @@
   "+base/synchronization/atomic_flag.h",
   "+base/synchronization/cancellation_flag.h",
   "+base/synchronization/lock.h",
+  "+base/task/common/lazy_now.h",
   "+base/task/common/scoped_defer_task_posting.h",
   "+base/task/common/task_annotator.h",
-  "+base/task/sequence_manager/lazy_now.h",
   "+base/task/sequence_manager/sequence_manager.h",
   "+base/task/sequence_manager/task_queue.h",
   "+base/task/sequence_manager/time_domain.h",
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
index 36c441b1..25c432cdf 100644
--- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -156,7 +156,6 @@
 
   std::unique_ptr<FrameScheduler> CreateFrameScheduler(
       FrameScheduler::Delegate* delegate,
-      BlameContext*,
       bool is_in_embedded_frame_tree,
       FrameScheduler::FrameType) override {
     return CreateDummyFrameScheduler();
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
index 4b190a2..c6e139c 100644
--- a/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/run_loop.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/sequence_manager.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
@@ -669,8 +670,7 @@
   idle_helper_->EnableLongIdlePeriod();
   CheckIdlePeriodStateIs("in_long_idle_period_paused");
   // There shouldn't be any delayed tasks posted by the idle helper when paused.
-  base::sequence_manager::LazyNow lazy_now_1(
-      test_task_runner_->GetMockTickClock());
+  base::LazyNow lazy_now_1(test_task_runner_->GetMockTickClock());
   EXPECT_FALSE(scheduler_helper_->GetNextWakeUp());
 
   // Posting a task should transition us to the an active state.
@@ -691,8 +691,7 @@
 
   // Once all task have been run we should go back to the paused state.
   CheckIdlePeriodStateIs("in_long_idle_period_paused");
-  base::sequence_manager::LazyNow lazy_now_2(
-      test_task_runner_->GetMockTickClock());
+  base::LazyNow lazy_now_2(test_task_runner_->GetMockTickClock());
   EXPECT_FALSE(scheduler_helper_->GetNextWakeUp());
 
   idle_helper_->EndIdlePeriod();
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
index 23660341..3619a99 100644
--- a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.cc b/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.cc
index fccb9ad..ea5077b 100644
--- a/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.cc
@@ -6,7 +6,6 @@
 
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
-#include "base/trace_event/blame_context.h"
 #include "base/trace_event/trace_event.h"
 
 namespace blink {
@@ -18,8 +17,7 @@
     Delegate* delegate)
     : idle_priority_task_runner_(std::move(idle_priority_task_runner)),
       control_task_runner_(std::move(control_task_runner)),
-      delegate_(delegate),
-      blame_context_(nullptr) {
+      delegate_(delegate) {
   weak_scheduler_ptr_ = weak_factory_.GetWeakPtr();
 }
 
@@ -99,18 +97,9 @@
   TRACE_EVENT1("renderer.scheduler", "SingleThreadIdleTaskRunner::RunTask",
                "allotted_time_ms",
                (deadline - base::TimeTicks::Now()).InMillisecondsF());
-  if (blame_context_)
-    blame_context_->Enter();
   std::move(idle_task).Run(deadline);
-  if (blame_context_)
-    blame_context_->Leave();
   delegate_->DidProcessIdleTask();
 }
 
-void SingleThreadIdleTaskRunner::SetBlameContext(
-    base::trace_event::BlameContext* blame_context) {
-  blame_context_ = blame_context;
-}
-
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h b/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h
index dade662..e2c83c8 100644
--- a/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h
+++ b/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h
@@ -16,12 +16,6 @@
 #include "base/time/time.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 
-namespace base {
-namespace trace_event {
-class BlameContext;
-}
-}  // namespace base
-
 namespace blink {
 namespace scheduler {
 class IdleHelper;
@@ -91,8 +85,6 @@
 
   bool RunsTasksInCurrentSequence() const;
 
-  void SetBlameContext(base::trace_event::BlameContext* blame_context);
-
  protected:
   virtual ~SingleThreadIdleTaskRunner();
 
@@ -114,8 +106,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> idle_priority_task_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_;
   std::multimap<base::TimeTicks, DelayedIdleTask> delayed_idle_tasks_;
-  Delegate* delegate_;                              // NOT OWNED
-  base::trace_event::BlameContext* blame_context_;  // Not owned.
+  Delegate* delegate_;  // NOT OWNED
   base::WeakPtr<SingleThreadIdleTaskRunner> weak_scheduler_ptr_;
   base::WeakPtrFactory<SingleThreadIdleTaskRunner> weak_factory_{this};
 };
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
index 5c32a8d..4eb1899 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
@@ -52,7 +52,7 @@
   throttler->UpdateQueueState(now);
 }
 
-void BudgetPool::EnableThrottling(base::sequence_manager::LazyNow* lazy_now) {
+void BudgetPool::EnableThrottling(base::LazyNow* lazy_now) {
   if (is_enabled_)
     return;
   is_enabled_ = true;
@@ -62,7 +62,7 @@
   UpdateStateForAllThrottlers(lazy_now->Now());
 }
 
-void BudgetPool::DisableThrottling(base::sequence_manager::LazyNow* lazy_now) {
+void BudgetPool::DisableThrottling(base::LazyNow* lazy_now) {
   if (!is_enabled_)
     return;
   is_enabled_ = false;
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
index 2a4ce8a..ca8d9015 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h
@@ -6,7 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_BUDGET_POOL_H_
 
 #include "base/callback.h"
-#include "base/task/sequence_manager/lazy_now.h"
+#include "base/task/common/lazy_now.h"
 #include "base/time/time.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
@@ -79,12 +79,12 @@
 
   // Enables this budget pool, allowing it to enforce its policies on its
   // queues.
-  void EnableThrottling(base::sequence_manager::LazyNow* now);
+  void EnableThrottling(base::LazyNow* now);
 
   // Disables this budget pool, stopping it from enforcing its policies on its
   // queues. UpdateQueueState() is invoked on all queues to update their wake up
   // times and fences.
-  void DisableThrottling(base::sequence_manager::LazyNow* now);
+  void DisableThrottling(base::LazyNow* now);
 
   bool IsThrottlingEnabled() const;
 
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
index e59d6a1..2146e6f9 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc
@@ -11,6 +11,7 @@
 #include "base/bind.h"
 #include "base/check_op.h"
 #include "base/memory/ptr_util.h"
+#include "base/task/common/lazy_now.h"
 #include "base/time/tick_clock.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
@@ -19,7 +20,7 @@
 namespace blink {
 namespace scheduler {
 
-using base::sequence_manager::LazyNow;
+using base::LazyNow;
 using base::sequence_manager::TaskQueue;
 
 TaskQueueThrottler::TaskQueueThrottler(
@@ -166,7 +167,7 @@
   task_queue_->UpdateWakeUp(&lazy_now);
 }
 
-void TaskQueueThrottler::OnWakeUp(base::sequence_manager::LazyNow* lazy_now) {
+void TaskQueueThrottler::OnWakeUp(base::LazyNow* lazy_now) {
   DCHECK(IsThrottled());
   for (BudgetPool* budget_pool : budget_pools_)
     budget_pool->OnWakeUp(lazy_now->Now());
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
index d38c356..a214d26b 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
@@ -15,6 +15,7 @@
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 namespace base {
+class LazyNow;
 namespace trace_event {
 class TracedValue;
 }
@@ -99,16 +100,16 @@
 
   // See GetNextAllowedWakeUp().
   absl::optional<base::sequence_manager::WakeUp> GetNextAllowedWakeUpImpl(
-      base::sequence_manager::LazyNow* lazy_now,
+      base::LazyNow* lazy_now,
       absl::optional<base::sequence_manager::WakeUp> next_wake_up,
       bool has_ready_task);
 
   // TaskQueue::Throttler implementation:
   absl::optional<base::sequence_manager::WakeUp> GetNextAllowedWakeUp(
-      base::sequence_manager::LazyNow* lazy_now,
+      base::LazyNow* lazy_now,
       absl::optional<base::sequence_manager::WakeUp> next_wake_up,
       bool has_ready_task) override;
-  void OnWakeUp(base::sequence_manager::LazyNow* lazy_now) override;
+  void OnWakeUp(base::LazyNow* lazy_now) override;
   void OnHasImmediateTask() override;
 
   void UpdateFence(base::TimeTicks now);
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
index a5e0c505..514b10c 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/sequence_manager.h"
 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
 #include "base/test/bind.h"
@@ -28,9 +29,9 @@
 // To avoid symbol collisions in jumbo builds.
 namespace task_queue_throttler_unittest {
 
+using base::LazyNow;
 using base::TestMockTimeTaskRunner;
 using base::TimeTicks;
-using base::sequence_manager::LazyNow;
 using base::sequence_manager::TaskQueue;
 using testing::ElementsAre;
 
@@ -105,8 +106,7 @@
     queue->SetOnTaskCompletedHandler(base::BindRepeating(
         [](TaskQueueThrottler* throttler,
            const base::sequence_manager::Task& task,
-           TaskQueue::TaskTiming* task_timing,
-           base::sequence_manager::LazyNow* lazy_now) {
+           TaskQueue::TaskTiming* task_timing, base::LazyNow* lazy_now) {
           task_timing->RecordTaskEnd(lazy_now);
           throttler->OnTaskRunTimeReported(task_timing->start_time(),
                                            task_timing->end_time());
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index 3adbada..be1023d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -10,17 +10,15 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/common/scoped_defer_task_posting.h"
 #include "base/task/common/task_annotator.h"
-#include "base/task/sequence_manager/lazy_now.h"
 #include "base/time/time.h"
-#include "base/trace_event/blame_context.h"
 #include "components/power_scheduler/power_mode.h"
 #include "components/power_scheduler/power_mode_arbiter.h"
 #include "components/power_scheduler/power_mode_voter.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/renderer/platform/back_forward_cache_utils.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -99,16 +97,13 @@
     frame_scheduler_->RemovePauseSubresourceLoadingHandle();
 }
 
-FrameSchedulerImpl::FrameSchedulerImpl(
-    PageSchedulerImpl* parent_page_scheduler,
-    FrameScheduler::Delegate* delegate,
-    base::trace_event::BlameContext* blame_context,
-    bool is_in_embedded_frame_tree,
-    FrameScheduler::FrameType frame_type)
+FrameSchedulerImpl::FrameSchedulerImpl(PageSchedulerImpl* parent_page_scheduler,
+                                       FrameScheduler::Delegate* delegate,
+                                       bool is_in_embedded_frame_tree,
+                                       FrameScheduler::FrameType frame_type)
     : FrameSchedulerImpl(parent_page_scheduler->GetMainThreadScheduler(),
                          parent_page_scheduler,
                          delegate,
-                         blame_context,
                          is_in_embedded_frame_tree,
                          frame_type) {}
 
@@ -116,7 +111,6 @@
     MainThreadSchedulerImpl* main_thread_scheduler,
     PageSchedulerImpl* parent_page_scheduler,
     FrameScheduler::Delegate* delegate,
-    base::trace_event::BlameContext* blame_context,
     bool is_in_embedded_frame_tree,
     FrameScheduler::FrameType frame_type)
     : frame_type_(frame_type),
@@ -124,7 +118,6 @@
       main_thread_scheduler_(main_thread_scheduler),
       parent_page_scheduler_(parent_page_scheduler),
       delegate_(delegate),
-      blame_context_(blame_context),
       throttling_state_(SchedulingLifecycleState::kNotThrottled),
       frame_visible_(true,
                      "FrameScheduler.FrameVisible",
@@ -204,7 +197,6 @@
     : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr,
                          /*parent_page_scheduler=*/nullptr,
                          /*delegate=*/nullptr,
-                         /*blame_context=*/nullptr,
                          /*is_in_embedded_frame_tree=*/false,
                          FrameType::kSubframe) {}
 
@@ -215,7 +207,6 @@
 
   queue->DetachFromMainThreadScheduler();
   DCHECK(!queue->GetFrameScheduler());
-  queue->SetBlameContext(nullptr);
 }
 
 }  // namespace
@@ -263,11 +254,10 @@
 
   // On tests, the scheduler helper might already be shut down and tick is not
   // available.
-  base::sequence_manager::LazyNow lazy_now =
+  base::LazyNow lazy_now =
       main_thread_scheduler_->GetTickClock()
-          ? base::sequence_manager::LazyNow(
-                main_thread_scheduler_->GetTickClock())
-          : base::sequence_manager::LazyNow(base::TimeTicks::Now());
+          ? base::LazyNow(main_thread_scheduler_->GetTickClock())
+          : base::LazyNow(base::TimeTicks::Now());
 
   if (cpu_time_budget_pool) {
     task_queue->RemoveFromBudgetPool(lazy_now.Now(), cpu_time_budget_pool);
@@ -278,8 +268,7 @@
 }
 
 void FrameSchedulerImpl::MoveTaskQueuesToCorrectWakeUpBudgetPool() {
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
 
   // The WakeUpBudgetPool is selected based on origin state, frame visibility
   // and page background state.
@@ -756,9 +745,6 @@
            !RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled());
 
   dict.Add("frame_task_queue_controller", frame_task_queue_controller_);
-
-  if (blame_context_)
-    dict.Add("blame_context", blame_context_);
 }
 
 void FrameSchedulerImpl::WriteIntoTrace(
@@ -1199,12 +1185,10 @@
     base::sequence_manager::TaskQueue::QueueEnabledVoter* voter) {
   DCHECK(parent_page_scheduler_);
 
-  task_queue->SetBlameContext(blame_context_);
   UpdateQueuePolicy(task_queue, voter);
 
   if (task_queue->CanBeThrottled()) {
-    base::sequence_manager::LazyNow lazy_now(
-        main_thread_scheduler_->GetTickClock());
+    base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
 
     CPUTimeBudgetPool* cpu_time_budget_pool =
         parent_page_scheduler_->background_cpu_time_budget_pool();
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index c5a92703..d9f0307e 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -38,9 +38,6 @@
 namespace sequence_manager {
 class TaskQueue;
 }  // namespace sequence_manager
-namespace trace_event {
-class BlameContext;
-}  // namespace trace_event
 }  // namespace base
 
 namespace ukm {
@@ -76,7 +73,6 @@
  public:
   FrameSchedulerImpl(PageSchedulerImpl* page_scheduler,
                      FrameScheduler::Delegate* delegate,
-                     base::trace_event::BlameContext* blame_context,
                      bool is_in_embedded_frame_tree,
                      FrameScheduler::FrameType frame_type);
   FrameSchedulerImpl(const FrameSchedulerImpl&) = delete;
@@ -208,7 +204,6 @@
   FrameSchedulerImpl(MainThreadSchedulerImpl* main_thread_scheduler,
                      PageSchedulerImpl* parent_page_scheduler,
                      FrameScheduler::Delegate* delegate,
-                     base::trace_event::BlameContext* blame_context,
                      bool is_in_embedded_frame_tree,
                      FrameScheduler::FrameType frame_type);
 
@@ -334,7 +329,6 @@
   MainThreadSchedulerImpl* const main_thread_scheduler_;  // NOT OWNED
   PageSchedulerImpl* parent_page_scheduler_;              // NOT OWNED
   FrameScheduler::Delegate* delegate_;                    // NOT OWNED
-  base::trace_event::BlameContext* blame_context_;        // NOT OWNED
   SchedulingLifecycleState throttling_state_;
   TraceableState<bool, TracingCategory::kInfo> frame_visible_;
   TraceableState<bool, TracingCategory::kInfo> frame_paused_;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index d1dc0a2..505ff3d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -84,11 +84,10 @@
 std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
     PageSchedulerImpl* page_scheduler,
     FrameScheduler::Delegate* delegate,
-    blink::BlameContext* blame_context,
     bool is_in_embedded_frame_tree,
     FrameScheduler::FrameType frame_type) {
   auto frame_scheduler = page_scheduler->CreateFrameScheduler(
-      delegate, blame_context, is_in_embedded_frame_tree, frame_type);
+      delegate, is_in_embedded_frame_tree, frame_type);
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
       static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
   return frame_scheduler_impl;
@@ -227,7 +226,7 @@
     frame_scheduler_delegate_ = std::make_unique<
         testing::StrictMock<FrameSchedulerDelegateForTesting>>();
     frame_scheduler_ = CreateFrameScheduler(
-        page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+        page_scheduler_.get(), frame_scheduler_delegate_.get(),
         /*is_in_embedded_frame_tree=*/false,
         FrameScheduler::FrameType::kSubframe);
   }
@@ -238,7 +237,7 @@
         testing::StrictMock<FrameSchedulerDelegateForTesting>>();
     frame_scheduler_ =
         CreateFrameScheduler(page_scheduler_.get(), new_delegate_.get(),
-                             nullptr, is_in_embedded_frame_tree, frame_type);
+                             is_in_embedded_frame_tree, frame_type);
     frame_scheduler_delegate_ = std::move(new_delegate_);
   }
 
@@ -1624,7 +1623,7 @@
   // Main thread scheduler is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -1687,7 +1686,7 @@
             TaskQueue::QueuePriority::kLowPriority);
 
   frame_scheduler_ =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -1719,7 +1718,7 @@
   // Main thread scheduler is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -1784,7 +1783,7 @@
             TaskQueue::QueuePriority::kNormalPriority);
 
   frame_scheduler_ =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -1817,7 +1816,7 @@
   // Main thread scheduler is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -1881,7 +1880,7 @@
             TaskQueue::QueuePriority::kNormalPriority);
 
   frame_scheduler_ =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -1914,7 +1913,7 @@
   // Main thread is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -1958,7 +1957,7 @@
   frame_scheduler_->OnFirstMeaningfulPaint();
 
   frame_scheduler_ =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -2073,7 +2072,7 @@
   // Main thread scheduler is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -2187,7 +2186,7 @@
   // Main thread scheduler is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
   main_frame_scheduler->OnFirstContentfulPaintInMainFrame();
@@ -2279,7 +2278,7 @@
 TEST_F(ResourceFetchPriorityExperimentOnlyWhenLoadingTest, DidChangePriority) {
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -2383,7 +2382,7 @@
   // Main thread is in the loading use case.
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -2963,7 +2962,7 @@
       nullptr, &mock_main_thread_scheduler, *agent_group_scheduler);
 
   std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler =
-      CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kMainFrame);
 
@@ -2988,7 +2987,7 @@
   // Test for direct subframes.
   {
     std::unique_ptr<FrameSchedulerImpl> subframe_scheduler =
-        CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+        CreateFrameScheduler(page_scheduler.get(), nullptr,
                              /*is_in_embedded_frame_tree=*/false,
                              FrameScheduler::FrameType::kSubframe);
 
@@ -3000,7 +2999,7 @@
   // Now test for embedded main frames.
   {
     std::unique_ptr<FrameSchedulerImpl> subframe_scheduler =
-        CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+        CreateFrameScheduler(page_scheduler.get(), nullptr,
                              /*is_in_embedded_frame_tree=*/true,
                              FrameScheduler::FrameType::kMainFrame);
 
@@ -3368,7 +3367,7 @@
   // associated throttled TaskRunner.
   std::unique_ptr<FrameSchedulerImpl> other_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToNearestMainFrame());
@@ -3423,7 +3422,7 @@
   // |other_task_runner| is throttled. It belongs to a different frame on the
   // same page.
   const auto other_frame_scheduler = CreateFrameScheduler(
-      page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+      page_scheduler_.get(), frame_scheduler_delegate_.get(),
       /*is_in_embedded_frame_tree=*/false,
       FrameScheduler::FrameType::kSubframe);
   const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
@@ -3551,7 +3550,7 @@
   // throughout the test.
   std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   cross_origin_frame_scheduler->SetCrossOriginToNearestMainFrame(true);
@@ -3708,7 +3707,7 @@
   void SetUp() override {
     FrameSchedulerImplTest::SetUp();
     scheduler_of_main_frame_ = CreateFrameScheduler(
-        page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+        page_scheduler_.get(), frame_scheduler_delegate_.get(),
         /*is_in_embedded_frame_tree=*/false,
         FrameScheduler::FrameType::kMainFrame);
   }
@@ -4064,7 +4063,7 @@
        VisibleCrossOriginFrameThrottling) {
   std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   page_scheduler_->SetPageVisible(true);
@@ -4099,7 +4098,7 @@
        HiddenCrossOriginFrameThrottling) {
   std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
       CreateFrameScheduler(page_scheduler_.get(),
-                           frame_scheduler_delegate_.get(), nullptr,
+                           frame_scheduler_delegate_.get(),
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   page_scheduler_->SetPageVisible(true);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
index 5991cd3..0504eaf7 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc
@@ -54,7 +54,7 @@
         agent_group_scheduler_->AsAgentGroupScheduler().CreatePageScheduler(
             nullptr);
     frame_scheduler_ = page_scheduler_->CreateFrameScheduler(
-        nullptr, nullptr, /*is_in_embedded_frame_tree=*/false,
+        nullptr, /*is_in_embedded_frame_tree=*/false,
         FrameScheduler::FrameType::kSubframe);
     frame_task_queue_controller_ = std::make_unique<FrameTaskQueueController>(
         scheduler_.get(),
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index ba10c19..abd8b0d2 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -59,6 +59,10 @@
 #include "third_party/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h"
 #include "v8/include/v8.h"
 
+namespace base {
+class LazyNow;
+}
+
 namespace blink {
 namespace scheduler {
 
@@ -2354,7 +2358,7 @@
     base::WeakPtr<MainThreadTaskQueue> queue,
     const base::sequence_manager::Task& task,
     TaskQueue::TaskTiming* task_timing,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   // Microtasks may detach the task queue and invalidate |queue|.
   PerformMicrotaskCheckpoint();
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index cf3cd823..978e63d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -56,6 +56,7 @@
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 namespace base {
+class LazyNow;
 class TaskObserver;
 }  // namespace base
 
@@ -355,7 +356,7 @@
       base::WeakPtr<MainThreadTaskQueue> queue,
       const base::sequence_manager::Task& task,
       base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-      base::sequence_manager::LazyNow* lazy_now);
+      base::LazyNow* lazy_now);
 
   void UpdateIpcTracking();
   void SetOnIPCTaskPostedWhileInBackForwardCacheIfNeeded();
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index f26c466..568bdb6 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -90,11 +90,10 @@
 std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
     PageSchedulerImpl* page_scheduler,
     FrameScheduler::Delegate* delegate,
-    blink::BlameContext* blame_context,
     bool is_in_embedded_frame_tree,
     FrameScheduler::FrameType frame_type) {
   auto frame_scheduler = page_scheduler->CreateFrameScheduler(
-      delegate, blame_context, is_in_embedded_frame_tree, frame_type);
+      delegate, is_in_embedded_frame_tree, frame_type);
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
       static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
   return frame_scheduler_impl;
@@ -464,7 +463,7 @@
         scheduler_.get(),
         static_cast<AgentGroupSchedulerImpl&>(*agent_group_scheduler_));
     main_frame_scheduler_ =
-        CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+        CreateFrameScheduler(page_scheduler_.get(), nullptr,
                              /*is_in_embedded_frame_tree=*/false,
                              FrameScheduler::FrameType::kMainFrame);
 
@@ -3238,7 +3237,7 @@
   scheduler_->AddPageScheduler(page_scheduler1.get());
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler1.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler1.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
index fa58dac7..2d62733f 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -155,7 +155,7 @@
 void MainThreadTaskQueue::OnTaskCompleted(
     const base::sequence_manager::Task& task,
     TaskQueue::TaskTiming* task_timing,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   if (main_thread_scheduler_) {
     main_thread_scheduler_->OnTaskCompleted(weak_ptr_factory_.GetWeakPtr(),
                                             task, task_timing, lazy_now);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
index f0b8bd2..3de6619b5 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/task/sequence_manager/time_domain.h"
@@ -419,7 +420,7 @@
 
   void OnTaskCompleted(const base::sequence_manager::Task& task,
                        TaskQueue::TaskTiming* task_timing,
-                       base::sequence_manager::LazyNow* lazy_now);
+                       base::LazyNow* lazy_now);
 
   void LogTaskExecution(perfetto::EventContext& ctx,
                         const base::sequence_manager::Task& task);
@@ -491,10 +492,6 @@
     return task_queue_->HasTaskToRunImmediatelyOrReadyDelayedTask();
   }
 
-  void SetBlameContext(base::trace_event::BlameContext* blame_context) {
-    task_queue_->SetBlameContext(blame_context);
-  }
-
   void SetShouldReportPostedTasksWhenDisabled(bool should_report) {
     task_queue_->SetShouldReportPostedTasksWhenDisabled(should_report);
   }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index dff06f7..4ea05075 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -353,8 +353,7 @@
 
 void PageSchedulerImpl::RegisterFrameSchedulerImpl(
     FrameSchedulerImpl* frame_scheduler) {
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
 
   MaybeInitializeWakeUpBudgetPools(&lazy_now);
   MaybeInitializeBackgroundCPUTimeBudgetPool(&lazy_now);
@@ -365,11 +364,10 @@
 
 std::unique_ptr<blink::FrameScheduler> PageSchedulerImpl::CreateFrameScheduler(
     FrameScheduler::Delegate* delegate,
-    blink::BlameContext* blame_context,
     bool is_in_embedded_frame_tree,
     FrameScheduler::FrameType frame_type) {
   auto frame_scheduler = std::make_unique<FrameSchedulerImpl>(
-      this, delegate, blame_context, is_in_embedded_frame_tree, frame_type);
+      this, delegate, is_in_embedded_frame_tree, frame_type);
   RegisterFrameSchedulerImpl(frame_scheduler.get());
   return frame_scheduler;
 }
@@ -475,8 +473,7 @@
       opted_out_from_aggressive_throttling) {
     opted_out_from_aggressive_throttling_ =
         opted_out_from_aggressive_throttling;
-    base::sequence_manager::LazyNow lazy_now(
-        main_thread_scheduler_->GetTickClock());
+    base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
     UpdateCPUTimeBudgetPool(&lazy_now);
     UpdateWakeUpBudgetPools(&lazy_now);
   }
@@ -558,7 +555,7 @@
     MainThreadTaskQueue* task_queue,
     FrameOriginType frame_origin_type,
     bool frame_visible,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   DCHECK(!task_queue->GetWakeUpBudgetPool());
   WakeUpBudgetPool* wake_up_budget_pool =
       GetWakeUpBudgetPool(task_queue, frame_origin_type, frame_visible);
@@ -568,7 +565,7 @@
 
 void PageSchedulerImpl::RemoveQueueFromWakeUpBudgetPool(
     MainThreadTaskQueue* task_queue,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   if (!task_queue->GetWakeUpBudgetPool())
     return;
   task_queue->RemoveFromBudgetPool(lazy_now->Now(),
@@ -607,7 +604,7 @@
 }
 
 void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool(
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   if (cpu_time_budget_pool_)
     return;
 
@@ -633,7 +630,7 @@
 }
 
 void PageSchedulerImpl::MaybeInitializeWakeUpBudgetPools(
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   if (HasWakeUpBudgetPools())
     return;
 
@@ -664,8 +661,7 @@
 
 void PageSchedulerImpl::UpdatePolicyOnVisibilityChange(
     NotificationPolicy notification_policy) {
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
 
   if (IsPageVisible()) {
     is_cpu_time_throttled_ = false;
@@ -701,8 +697,7 @@
   do_throttle_cpu_time_callback_.Cancel();
   is_cpu_time_throttled_ = true;
 
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
   UpdateCPUTimeBudgetPool(&lazy_now);
   NotifyFrames();
 }
@@ -711,14 +706,12 @@
   do_intensively_throttle_wake_ups_callback_.Cancel();
   are_wake_ups_intensively_throttled_ = true;
 
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
   UpdateWakeUpBudgetPools(&lazy_now);
   NotifyFrames();
 }
 
-void PageSchedulerImpl::UpdateCPUTimeBudgetPool(
-    base::sequence_manager::LazyNow* lazy_now) {
+void PageSchedulerImpl::UpdateCPUTimeBudgetPool(base::LazyNow* lazy_now) {
   if (!cpu_time_budget_pool_)
     return;
 
@@ -739,8 +732,7 @@
     // the user's attention. Cross-origin frames are not affected, since they
     // shouldn't be able to observe that the page title or favicon was updated.
     had_recent_title_or_favicon_update_ = true;
-    base::sequence_manager::LazyNow lazy_now(
-        main_thread_scheduler_->GetTickClock());
+    base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
     UpdateWakeUpBudgetPools(&lazy_now);
     // Re-enable intensive throttling from a delayed task.
     reset_had_recent_title_or_favicon_update_.Cancel();
@@ -753,8 +745,7 @@
 void PageSchedulerImpl::ResetHadRecentTitleOrFaviconUpdate() {
   had_recent_title_or_favicon_update_ = false;
 
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
   UpdateWakeUpBudgetPools(&lazy_now);
 
   NotifyFrames();
@@ -773,8 +764,7 @@
     return kDefaultThrottledWakeUpInterval;
 }
 
-void PageSchedulerImpl::UpdateWakeUpBudgetPools(
-    base::sequence_manager::LazyNow* lazy_now) {
+void PageSchedulerImpl::UpdateWakeUpBudgetPools(base::LazyNow* lazy_now) {
   if (!same_origin_intensive_wake_up_budget_pool_)
     return;
 
@@ -869,8 +859,7 @@
 
   // Update the WakeUpBudgetPools' interval everytime task queues change their
   // attached WakeUpBudgetPools
-  base::sequence_manager::LazyNow lazy_now(
-      main_thread_scheduler_->GetTickClock());
+  base::LazyNow lazy_now(main_thread_scheduler_->GetTickClock());
   UpdateWakeUpBudgetPools(&lazy_now);
 }
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 4f01301..10cd56d 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/time/time.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -26,12 +27,6 @@
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
-namespace base {
-namespace trace_event {
-class BlameContext;
-}  // namespace trace_event
-}  // namespace base
-
 namespace blink {
 namespace scheduler {
 namespace page_scheduler_impl_unittest {
@@ -80,7 +75,6 @@
 
   std::unique_ptr<FrameScheduler> CreateFrameScheduler(
       FrameScheduler::Delegate* delegate,
-      BlameContext*,
       bool is_in_embedded_frame_tree,
       FrameScheduler::FrameType) override;
   void AudioStateChanged(bool is_audio_playing) override;
@@ -207,30 +201,27 @@
   void AddQueueToWakeUpBudgetPool(MainThreadTaskQueue* task_queue,
                                   FrameOriginType frame_origin_type,
                                   bool frame_visible,
-                                  base::sequence_manager::LazyNow* lazy_now);
-  void RemoveQueueFromWakeUpBudgetPool(
-      MainThreadTaskQueue* task_queue,
-      base::sequence_manager::LazyNow* lazy_now);
+                                  base::LazyNow* lazy_now);
+  void RemoveQueueFromWakeUpBudgetPool(MainThreadTaskQueue* task_queue,
+                                       base::LazyNow* lazy_now);
   // Returns the WakeUpBudgetPool to use for |task_queue| which belongs to a
   // frame with |frame_origin_type| and visibility |frame_visible|.
   WakeUpBudgetPool* GetWakeUpBudgetPool(MainThreadTaskQueue* task_queue,
                                         FrameOriginType frame_origin_type,
                                         bool frame_visible);
   // Initializes WakeUpBudgetPools, if not already initialized.
-  void MaybeInitializeWakeUpBudgetPools(
-      base::sequence_manager::LazyNow* lazy_now);
+  void MaybeInitializeWakeUpBudgetPools(base::LazyNow* lazy_now);
 
   CPUTimeBudgetPool* background_cpu_time_budget_pool();
-  void MaybeInitializeBackgroundCPUTimeBudgetPool(
-      base::sequence_manager::LazyNow* lazy_now);
+  void MaybeInitializeBackgroundCPUTimeBudgetPool(base::LazyNow* lazy_now);
 
   // Depending on page visibility, either turns throttling off, or schedules a
   // call to enable it after a grace period.
   void UpdatePolicyOnVisibilityChange(NotificationPolicy notification_policy);
 
   // Adjusts settings of budget pools depending on current state of the page.
-  void UpdateCPUTimeBudgetPool(base::sequence_manager::LazyNow* lazy_now);
-  void UpdateWakeUpBudgetPools(base::sequence_manager::LazyNow* lazy_now);
+  void UpdateCPUTimeBudgetPool(base::LazyNow* lazy_now);
+  void UpdateWakeUpBudgetPools(base::LazyNow* lazy_now);
   base::TimeDelta GetIntensiveWakeUpThrottlingInterval(
       bool is_same_origin) const;
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
index b9917b0..a173aa0 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -64,11 +64,10 @@
 std::unique_ptr<FrameSchedulerImpl> CreateFrameScheduler(
     PageSchedulerImpl* page_scheduler,
     FrameScheduler::Delegate* delegate,
-    blink::BlameContext* blame_context,
     bool is_in_embedded_frame_tree,
     FrameScheduler::FrameType frame_type) {
   auto frame_scheduler = page_scheduler->CreateFrameScheduler(
-      delegate, blame_context, is_in_embedded_frame_tree, frame_type);
+      delegate, is_in_embedded_frame_tree, frame_type);
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler_impl(
       static_cast<FrameSchedulerImpl*>(frame_scheduler.release()));
   return frame_scheduler_impl;
@@ -117,7 +116,7 @@
         CreatePageScheduler(page_scheduler_delegate_.get(), scheduler_.get(),
                             *agent_group_scheduler_);
     frame_scheduler_ =
-        CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+        CreateFrameScheduler(page_scheduler_.get(), nullptr,
                              /*is_in_embedded_frame_tree=*/false,
                              FrameScheduler::FrameType::kSubframe);
   }
@@ -270,22 +269,22 @@
 TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersBefore) {
   std::unique_ptr<blink::FrameScheduler> frame1(
       page_scheduler_->CreateFrameScheduler(
-          nullptr, nullptr, /*is_in_embedded_frame_tree=*/false,
+          nullptr, /*is_in_embedded_frame_tree=*/false,
           FrameScheduler::FrameType::kSubframe));
   std::unique_ptr<blink::FrameScheduler> frame2(
       page_scheduler_->CreateFrameScheduler(
-          nullptr, nullptr, /*is_in_embedded_frame_tree=*/false,
+          nullptr, /*is_in_embedded_frame_tree=*/false,
           FrameScheduler::FrameType::kSubframe));
 }
 
 TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersAfter) {
   std::unique_ptr<blink::FrameScheduler> frame1(
       page_scheduler_->CreateFrameScheduler(
-          nullptr, nullptr, /*is_in_embedded_frame_tree=*/false,
+          nullptr, /*is_in_embedded_frame_tree=*/false,
           FrameScheduler::FrameType::kSubframe));
   std::unique_ptr<blink::FrameScheduler> frame2(
       page_scheduler_->CreateFrameScheduler(
-          nullptr, nullptr, /*is_in_embedded_frame_tree=*/false,
+          nullptr, /*is_in_embedded_frame_tree=*/false,
           FrameScheduler::FrameType::kSubframe));
   page_scheduler_.reset();
 }
@@ -373,7 +372,7 @@
   std::unique_ptr<PageSchedulerImpl> page_scheduler2 =
       CreatePageScheduler(nullptr, scheduler_.get(), *agent_group_scheduler_);
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
-      CreateFrameScheduler(page_scheduler2.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler2.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
@@ -663,7 +662,7 @@
   vtc->SetVirtualTimePolicy(VirtualTimePolicy::kPause);
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
@@ -695,7 +694,7 @@
 TEST_F(PageSchedulerImplTest, DeleteFrameSchedulers_InTask) {
   for (int i = 0; i < 10; i++) {
     FrameSchedulerImpl* frame_scheduler =
-        CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+        CreateFrameScheduler(page_scheduler_.get(), nullptr,
                              /*is_in_embedded_frame_tree=*/false,
                              FrameScheduler::FrameType::kSubframe)
             .release();
@@ -717,7 +716,7 @@
   page_scheduler_->SetPageVisible(false);
 
   FrameSchedulerImpl* frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe)
           .release();
@@ -772,7 +771,7 @@
   vtc->SetVirtualTimePolicy(VirtualTimePolicy::kDeterministicLoading);
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
@@ -839,7 +838,7 @@
   base::TimeTicks time_second_task;
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
@@ -874,7 +873,7 @@
   vtc->SetVirtualTimePolicy(VirtualTimePolicy::kDeterministicLoading);
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
@@ -923,7 +922,7 @@
   Vector<int> run_order;
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler_.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   VirtualTimeController* vtc = page_scheduler_->GetVirtualTimeController();
@@ -1143,10 +1142,9 @@
   base::TimeTicks start_time = test_task_runner_->NowTicks();
 
   Vector<base::TimeTicks> run_times;
-  frame_scheduler_ =
-      CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr,
-                           /*is_in_embedded_frame_tree=*/false,
-                           FrameScheduler::FrameType::kSubframe);
+  frame_scheduler_ = CreateFrameScheduler(page_scheduler_.get(), nullptr,
+                                          /*is_in_embedded_frame_tree=*/false,
+                                          FrameScheduler::FrameType::kSubframe);
   page_scheduler_->SetPageVisible(true);
   EXPECT_FALSE(page_scheduler_->IsCPUTimeThrottled());
 
@@ -1204,11 +1202,11 @@
   Vector<base::TimeTicks> run_times;
 
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler1 =
-      CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
   std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
-      CreateFrameScheduler(page_scheduler.get(), nullptr, nullptr,
+      CreateFrameScheduler(page_scheduler.get(), nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            FrameScheduler::FrameType::kSubframe);
 
diff --git a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
index b5a5349..a47412c 100644
--- a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_PAGE_SCHEDULER_H_
 
 #include <memory>
-#include "third_party/blink/public/platform/blame_context.h"
 #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -59,11 +58,9 @@
   virtual bool IsInBackForwardCache() const = 0;
 
   // Creates a new FrameScheduler. The caller is responsible for deleting
-  // it. All tasks executed by the frame scheduler will be attributed to
-  // |blame_context|.
+  // it.
   virtual std::unique_ptr<FrameScheduler> CreateFrameScheduler(
       FrameScheduler::Delegate* delegate,
-      BlameContext*,
       bool is_in_embedded_frame_tree,
       FrameScheduler::FrameType) = 0;
 
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
index f9fe067..e029c7a05 100644
--- a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
@@ -59,14 +59,14 @@
       : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr,
                            /*parent_page_scheduler=*/nullptr,
                            /*delegate=*/delegate,
-                           /*blame_context=*/nullptr,
                            /*is_in_embedded_frame_tree=*/false,
                            /*frame_type=*/frame_type),
         page_scheduler_(page_scheduler),
         is_page_visible_(is_page_visible),
         is_frame_visible_(is_frame_visible),
         frame_type_(frame_type),
-        is_cross_origin_to_nearest_main_frame_(is_cross_origin_to_nearest_main_frame),
+        is_cross_origin_to_nearest_main_frame_(
+            is_cross_origin_to_nearest_main_frame),
         is_exempt_from_throttling_(is_exempt_from_throttling) {
     DCHECK(frame_type_ != FrameType::kMainFrame ||
            !is_cross_origin_to_nearest_main_frame);
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
index 426386b4..b1168d2 100644
--- a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
@@ -62,7 +62,6 @@
 
   std::unique_ptr<FrameScheduler> CreateFrameScheduler(
       FrameScheduler::Delegate* delegate,
-      BlameContext* blame_context,
       bool is_in_embedded_frame_tree,
       FrameScheduler::FrameType frame_type) override {
     return nullptr;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
index 1cb304e..6a84c226 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
@@ -53,7 +53,7 @@
     NonMainThreadTaskQueue* worker_task_queue,
     const base::sequence_manager::Task& task,
     base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   task_timing->RecordTaskEnd(lazy_now);
   DispatchOnTaskCompletionCallbacks();
   compositor_metrics_helper_.RecordTaskMetrics(task, *task_timing);
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
index 87d9747..8ed17fb 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h"
 
 namespace base {
+class LazyNow;
 class TaskObserver;
 }
 
@@ -38,7 +39,7 @@
       NonMainThreadTaskQueue* worker_task_queue,
       const base::sequence_manager::Task& task,
       base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-      base::sequence_manager::LazyNow* lazy_now) override;
+      base::LazyNow* lazy_now) override;
 
   // WebThreadScheduler:
   scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
index 08fb101..4dd40ad 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
@@ -20,6 +20,10 @@
 #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h"
 
+namespace base {
+class LazyNow;
+}
+
 namespace blink {
 namespace scheduler {
 
@@ -56,7 +60,7 @@
       NonMainThreadTaskQueue* worker_task_queue,
       const base::sequence_manager::Task& task,
       base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-      base::sequence_manager::LazyNow* lazy_now) = 0;
+      base::LazyNow* lazy_now) = 0;
 
   // ThreadSchedulerBase:
   scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner() override;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.cc b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.cc
index 8481a30..d7c1e210 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.cc
@@ -45,7 +45,7 @@
 void NonMainThreadTaskQueue::OnTaskCompleted(
     const base::sequence_manager::Task& task,
     TaskQueue::TaskTiming* task_timing,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   // |non_main_thread_scheduler_| can be nullptr in tests.
   if (non_main_thread_scheduler_) {
     non_main_thread_scheduler_->OnTaskCompleted(this, task, task_timing,
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
index 24d8e0b..a379e02 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_TASK_QUEUE_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_TASK_QUEUE_H_
 
+#include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/platform/task_type.h"
@@ -33,7 +34,7 @@
   void OnTaskCompleted(
       const base::sequence_manager::Task& task,
       base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-      base::sequence_manager::LazyNow* lazy_now);
+      base::LazyNow* lazy_now);
 
   scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner(
       TaskType task_type) {
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
index 7b5ced98..887ee75 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
@@ -135,7 +135,6 @@
                 nullptr)),
         frame_scheduler_(page_scheduler_->CreateFrameScheduler(
             nullptr,
-            nullptr,
             /*is_in_embedded_frame_tree=*/false,
             FrameScheduler::FrameType::kMainFrame)) {}
 
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
index 47a0d052..ad7cba9 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -201,7 +201,7 @@
     NonMainThreadTaskQueue* task_queue,
     const base::sequence_manager::Task& task,
     TaskQueue::TaskTiming* task_timing,
-    base::sequence_manager::LazyNow* lazy_now) {
+    base::LazyNow* lazy_now) {
   PerformMicrotaskCheckpoint();
 
   task_timing->RecordTaskEnd(lazy_now);
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
index 9969f3b..2666ac0 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h"
 
 namespace base {
+class LazyNow;
 class TaskObserver;
 namespace sequence_manager {
 class SequenceManager;
@@ -67,7 +68,7 @@
       NonMainThreadTaskQueue* worker_task_queue,
       const base::sequence_manager::Task& task,
       base::sequence_manager::TaskQueue::TaskTiming* task_timing,
-      base::sequence_manager::LazyNow* lazy_now) override;
+      base::LazyNow* lazy_now) override;
 
   SchedulerHelper* GetSchedulerHelperForTesting();
   base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
diff --git a/third_party/blink/renderer/platform/testing/run_all_tests.cc b/third_party/blink/renderer/platform/testing/run_all_tests.cc
index ad13b5b6..86d3d85 100644
--- a/third_party/blink/renderer/platform/testing/run_all_tests.cc
+++ b/third_party/blink/renderer/platform/testing/run_all_tests.cc
@@ -65,7 +65,7 @@
   // Some unittests depend on specific fonts provided by the system (e.g. some
   // tests load Arial). On Fuchsia the default font set contains only Roboto.
   // Load //third_party/test_fonts to make these tests pass on Fuchsia.
-  skia::ConfigureTestFont();
+  skia::InitializeSkFontMgrForTest();
 #endif
 
   {
diff --git a/third_party/blink/renderer/platform/timer_test.cc b/third_party/blink/renderer/platform/timer_test.cc
index e9996469..57db73fd 100644
--- a/third_party/blink/renderer/platform/timer_test.cc
+++ b/third_party/blink/renderer/platform/timer_test.cc
@@ -6,6 +6,8 @@
 
 #include <memory>
 #include <queue>
+
+#include "base/task/common/lazy_now.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
@@ -63,7 +65,7 @@
   // to the delay in seconds till the next pending delayed task is scheduled to
   // fire.
   bool TimeTillNextDelayedTask(base::TimeDelta* time) const {
-    base::sequence_manager::LazyNow lazy_now(platform_->NowTicks());
+    base::LazyNow lazy_now(platform_->NowTicks());
     auto* scheduler_helper =
         platform_->GetMainThreadScheduler()->GetSchedulerHelperForTesting();
     scheduler_helper->ReclaimMemory();
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
index bac81cf1a..ea815ee 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
@@ -658,7 +658,7 @@
             self.is_extra_result = True
             return
 
-        assert fs.exists(path)
+        assert fs.exists(path), path + "does not exist"
         if path.endswith('.txt'):
             content = fs.read_text_file(path)
             self.is_extra_result = not content or is_all_pass_testharness_result(
diff --git a/third_party/blink/tools/blinkpy/common/net/web.py b/third_party/blink/tools/blinkpy/common/net/web.py
index 8315076..1e13477 100644
--- a/third_party/blink/tools/blinkpy/common/net/web.py
+++ b/third_party/blink/tools/blinkpy/common/net/web.py
@@ -30,9 +30,13 @@
 
 import six
 from six.moves import urllib
+import time
+import logging
 
 from blinkpy.common.net.network_transaction import NetworkTransaction
 
+_log = logging.getLogger(__name__)
+
 
 class Web(object):
     class _HTTPRedirectHandler2(urllib.request.HTTPRedirectHandler):  # pylint:disable=no-init
@@ -43,7 +47,7 @@
             # otherwise, HTTPRedirectHandler will throw a HTTPError.
             return self.http_error_301(req, fp, 301, msg, headers)
 
-    def get_binary(self, url, return_none_on_404=False):
+    def get_binary(self, url, return_none_on_404=False, retries=0):
         def make_request():
             response = self.request('GET',
                                     url,
@@ -58,6 +62,17 @@
                 return gzip_decoder.read()
             return response.read()
 
+        if retries > 0:
+            for i in range(retries):
+                try:
+                    return NetworkTransaction(
+                        return_none_on_404=return_none_on_404).run(
+                            make_request)
+                except six.moves.urllib.error.URLError as error:
+                    _log.error(
+                        "Received URLError: %s. Retrying in 10"
+                        " seconds for the %s time...", error, i + 1)
+                    time.sleep(10)
         return NetworkTransaction(
             return_none_on_404=return_none_on_404).run(make_request)
 
diff --git a/third_party/blink/tools/blinkpy/common/net/web_mock.py b/third_party/blink/tools/blinkpy/common/net/web_mock.py
index c7bbbeb..ae438a1 100644
--- a/third_party/blink/tools/blinkpy/common/net/web_mock.py
+++ b/third_party/blink/tools/blinkpy/common/net/web_mock.py
@@ -35,7 +35,7 @@
         self.urls_fetched = []
         self.responses = responses or []
 
-    def get_binary(self, url, return_none_on_404=False):
+    def get_binary(self, url, return_none_on_404=False, retries=0):  # pylint: disable=unused-argument
         self.urls_fetched.append(url)
         if url in self.urls:
             return self.urls[url]
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py
index b1d55f4..81d2ad4 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_test.py
@@ -127,8 +127,9 @@
         else:
             _log.debug('Retrieving source %s for target %s.', source_baseline,
                        target_baseline)
-            data = self._tool.web.get_binary(
-                source_baseline, return_none_on_404=True)
+            data = self._tool.web.get_binary(source_baseline,
+                                             return_none_on_404=True,
+                                             retries=5)
 
         if not data:
             # We don't just remove the file because the test may create empty
diff --git a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
index 8f68cee80..457f7ff 100644
--- a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
+++ b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
@@ -282,9 +282,6 @@
     failures.extend(_check_never_fix_tests(host, port, path, expectations))
     failures.extend(
         _check_stable_webexposed_not_disabled(host, path, expectations))
-    if path in PRODUCTS_TO_EXPECTATION_FILE_PATHS.values():
-        failures.extend(_check_non_wpt_in_android_override(
-            host, port, path, expectations))
     # TODO(crbug.com/1080691): Change this to failures once
     # wpt_expectations_updater is fixed.
     warnings.extend(
@@ -292,17 +289,6 @@
     return failures, warnings
 
 
-def _check_non_wpt_in_android_override(host, port, path, expectations):
-    failures = []
-    for exp in expectations:
-        if exp.test and not port.is_wpt_test(exp.test):
-            error = "{}:{} Expectation '{}' is for a non WPT test".format(
-                host.filesystem.basename(path), exp.lineno, exp.to_string())
-            failures.append(error)
-            _log.error(error)
-    return failures
-
-
 def _check_stable_webexposed_not_disabled(host, path, expectations):
     if not host.filesystem.basename(path) == "TestExpectations":
         return []
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
index dec96f5..68ec2dd 100644
--- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
+++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -4,7 +4,6 @@
 # crbug.com/1138028 tracks the removal of these failure expectations
 
 # Unintentional failure
-accessibility/aom-click-action.html [ Skip ]
 external/wpt/accessibility/crashtests/serialize-with-no-document.html [ Skip ]
 external/wpt/accessibility/crashtests/svg-mouse-listener.html [ Skip ]
 external/wpt/css/css-backgrounds/background-repeat-space-5.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index e7673a0..40449f5d 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3152,7 +3152,6 @@
 crbug.com/937101 [ Mac ] external/wpt/css/css-values/ic-unit-003.html [ Failure ]
 crbug.com/937101 [ Mac ] external/wpt/css/css-values/ic-unit-009.html [ Failure ]
 crbug.com/937101 [ Mac ] external/wpt/css/css-values/ic-unit-010.html [ Failure ]
-crbug.com/937101 [ Mac ] external/wpt/css/css-values/ic-unit-011.html [ Failure ]
 crbug.com/937101 external/wpt/css/css-values/ic-unit-012.html [ Failure ]
 crbug.com/937104 external/wpt/css/css-values/lh-unit-002.html [ Failure ]
 crbug.com/937104 external/wpt/css/css-values/lh-unit-001.html [ Failure ]
diff --git a/third_party/blink/web_tests/accessibility/virtual-node-build-parent.html b/third_party/blink/web_tests/accessibility/virtual-node-build-parent.html
index 4ae8abe..3719959 100644
--- a/third_party/blink/web_tests/accessibility/virtual-node-build-parent.html
+++ b/third_party/blink/web_tests/accessibility/virtual-node-build-parent.html
@@ -20,15 +20,19 @@
     main.accessibleNode.appendChild(button_accNode);
 
     var axMain = accessibilityController.accessibleElementById("main");
-    var axButton = axMain.childAtIndex(0);
+    assert_equals(axMain.childAtIndex(0).role, 'AXRole: AXStaticText');
+    assert_equals(axMain.childAtIndex(1).role, 'AXRole: AXCheckBox');
+    var axButton = axMain.childAtIndex(2);
+    assert_equals(axButton.role, 'AXRole: AXButton');
 
     // Remove checkbox will cause ChildrenChanged called on axMain, which will
-    // remove all its children in the AXObjectCache.
+    // recompute all of its children in the AXObjectCache.
     checkbox.remove();
+    assert_equals(axMain.childAtIndex(0).role, 'AXRole: AXStaticText');
 
     // Try to fetch axButton, since its detached from its parent axMain, we need
     // to recompute its parent. Make sure no DCHECK or crash occurs.
-    axButton = axMain.childAtIndex(0);
+    assert_equals(axMain.childAtIndex(1).role, 'AXRole: AXButton');
 });
 </script>
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/crashtests/text-decoration-on-empty-first-line-crash.html b/third_party/blink/web_tests/external/wpt/css/css-text-decor/crashtests/text-decoration-on-empty-first-line-crash.html
new file mode 100644
index 0000000..058cf9f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/crashtests/text-decoration-on-empty-first-line-crash.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1347030">
+<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-decoration-line-property">
+<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
+<style>
+div::first-line {
+  text-decoration: line-through;
+}
+</style>
+<div><span></span></div>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/block-view-timeline-current-time.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/block-view-timeline-current-time.tentative.html
index 6e60db2..878b4a54 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/block-view-timeline-current-time.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/block-view-timeline-current-time.tentative.html
@@ -109,22 +109,22 @@
     const timeline = anim.timeline;
     await anim.ready;
 
-    assert_percents_equal(timeline.currentTime, 0,
+    assert_percents_equal(timeline.currentTime, 50,
                           "Timeline's currentTime at container start boundary");
-    assert_percents_equal(anim.currentTime, 0,
+    assert_percents_equal(anim.currentTime, 50,
                           "Animation's currentTime at container start boundary");
-    assert_equals(getComputedStyle(target).opacity, "0.3",
+    assert_equals(getComputedStyle(target).opacity, "0.5",
                   'Effect enters active phase at container start boundary');
 
 
     // Advance to midpoint
     container.scrollTop = 100;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 50,
+    assert_percents_equal(timeline.currentTime, 75,
                           "Timeline's current time at start offset");
-    assert_percents_equal(anim.currentTime, 50,
+    assert_percents_equal(anim.currentTime, 75,
                           "Animation's current time at start offset");
-    assert_equals(getComputedStyle(target).opacity, '0.5',
+    assert_equals(getComputedStyle(target).opacity, '0.6',
                   'Effect at the start of the active phase');
 
     // Advance to end-offset
@@ -140,14 +140,14 @@
     // Advance to scroll limit.
     container.scrollTop = 800;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 400,
+    assert_percents_equal(timeline.currentTime, 250,
                           "Timeline's current time at start offset");
     assert_percents_equal(anim.currentTime, 100,
                           "Animation's current time at start offset");
     assert_equals(getComputedStyle(target).opacity, '1',
                   'Effect at the start of the active phase');
 
-  }, 'View timeline clamps starting scroll offset at 0px');
+  }, 'View timeline does not clamp starting scroll offset at 0');
 
   promise_test(async t => {
     const trailing = document.getElementById('trailing-space');
@@ -164,9 +164,9 @@
     await anim.ready;
 
     // Initially in before phase.
-    assert_percents_equal(timeline.currentTime, -300,
+    assert_percents_equal(timeline.currentTime, -150,
                           "Timeline's currentTime at container start boundary");
-    assert_percents_equal(anim.currentTime, -300,
+    assert_percents_equal(anim.currentTime, -150,
                           "Animation's currentTime at container start boundary");
     assert_equals(getComputedStyle(target).opacity, "1",
                   'Effect enters active phase at container start boundary');
@@ -181,26 +181,26 @@
     assert_equals(getComputedStyle(target).opacity, '0.3',
                   'Effect at the start of the active phase');
 
-    // Advance to midpoint
+    // Advance to midpoint.
     container.scrollTop = 700;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 50,
+    assert_percents_equal(timeline.currentTime, 25,
                           "Timeline's current time at start offset");
-    assert_percents_equal(anim.currentTime, 50,
+    assert_percents_equal(anim.currentTime, 25,
                           "Animation's current time at start offset");
-    assert_equals(getComputedStyle(target).opacity, '0.5',
+    assert_equals(getComputedStyle(target).opacity, '0.4',
                   'Effect at the start of the active phase');
 
     // Advance to end offset.
     container.scrollTop = 800;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 100,
+    assert_percents_equal(timeline.currentTime, 50,
                           "Timeline's currentTime at max scroll offset");
-    assert_percents_equal(anim.currentTime, 100,
+    assert_percents_equal(anim.currentTime, 50,
                           "Animation's currentTime at max scroll offset");
-    assert_equals(getComputedStyle(target).opacity, "0.7",
+    assert_equals(getComputedStyle(target).opacity, "0.5",
                   'Effect at end of active phase');
-  }, 'View timeline clamps end scroll offset at max scroll');
+  }, 'View timeline  does not clamp end scroll offset at max scroll');
 
 </script>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/inline-view-timeline-current-time.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/inline-view-timeline-current-time.tentative.html
index 4cd6394..538bffb 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/inline-view-timeline-current-time.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/view-timelines/inline-view-timeline-current-time.tentative.html
@@ -122,22 +122,22 @@
     const timeline = anim.timeline;
     await anim.ready;
 
-    assert_percents_equal(timeline.currentTime, 0,
+    assert_percents_equal(timeline.currentTime, 50,
                           "Timeline's currentTime at container start boundary");
-    assert_percents_equal(anim.currentTime, 0,
+    assert_percents_equal(anim.currentTime, 50,
                           "Animation's currentTime at container start boundary");
-    assert_equals(getComputedStyle(target).opacity, "0.3",
+    assert_equals(getComputedStyle(target).opacity, "0.5",
                   'Effect enters active phase at container start boundary');
 
 
     // Advance to midpoint
     container.scrollLeft = 100;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 50,
+    assert_percents_equal(timeline.currentTime, 75,
                           "Timeline's current time at start offset");
-    assert_percents_equal(anim.currentTime, 50,
+    assert_percents_equal(anim.currentTime, 75,
                           "Animation's current time at start offset");
-    assert_equals(getComputedStyle(target).opacity, '0.5',
+    assert_equals(getComputedStyle(target).opacity, '0.6',
                   'Effect at the start of the active phase');
 
     // Advance to end-offset
@@ -153,14 +153,14 @@
     // Advance to scroll limit.
     container.scrollLeft = 800;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 400,
+    assert_percents_equal(timeline.currentTime, 250,
                           "Timeline's current time at start offset");
     assert_percents_equal(anim.currentTime, 100,
                           "Animation's current time at start offset");
     assert_equals(getComputedStyle(target).opacity, '1',
                   'Effect at the start of the active phase');
 
-  }, 'View timeline clamps starting scroll offset at 0px');
+  }, 'View timeline does not clamp starting scroll offset at 0');
 
   promise_test(async t => {
     const trailing = document.getElementById('trailing-space');
@@ -179,9 +179,9 @@
     await anim.ready;
 
     // Initially in before phase.
-    assert_percents_equal(timeline.currentTime, -300,
+    assert_percents_equal(timeline.currentTime, -150,
                           "Timeline's currentTime at container start boundary");
-    assert_percents_equal(anim.currentTime, -300,
+    assert_percents_equal(anim.currentTime, -150,
                           "Animation's currentTime at container start boundary");
     assert_equals(getComputedStyle(target).opacity, "1",
                   'Effect enters active phase at container start boundary');
@@ -199,23 +199,23 @@
     // Advance to midpoint
     container.scrollLeft = 700;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 50,
+    assert_percents_equal(timeline.currentTime, 25,
                           "Timeline's current time at start offset");
-    assert_percents_equal(anim.currentTime, 50,
+    assert_percents_equal(anim.currentTime, 25,
                           "Animation's current time at start offset");
-    assert_equals(getComputedStyle(target).opacity, '0.5',
+    assert_equals(getComputedStyle(target).opacity, '0.4',
                   'Effect at the start of the active phase');
 
     // Advance to end offset.
     container.scrollLeft = 800;
     await waitForNextFrame();
-    assert_percents_equal(timeline.currentTime, 100,
+    assert_percents_equal(timeline.currentTime, 50,
                           "Timeline's currentTime at max scroll offset");
-    assert_percents_equal(anim.currentTime, 100,
+    assert_percents_equal(anim.currentTime, 50,
                           "Animation's currentTime at max scroll offset");
-    assert_equals(getComputedStyle(target).opacity, "0.7",
+    assert_equals(getComputedStyle(target).opacity, "0.5",
                   'Effect at end of active phase');
-  }, 'View timeline clamps end scroll offset at max scroll');
+  }, 'View timeline does not clamp end scroll offset at max scroll');
 
 
   promise_test(async t => {
diff --git a/third_party/blink/web_tests/media/track/track-css-user-settings-override-internal-settings.html b/third_party/blink/web_tests/media/track/track-css-user-settings-override-internal-settings.html
index 0f340e1..28410ef 100644
--- a/third_party/blink/web_tests/media/track/track-css-user-settings-override-internal-settings.html
+++ b/third_party/blink/web_tests/media/track/track-css-user-settings-override-internal-settings.html
@@ -43,7 +43,6 @@
         internals.settings.setTextTrackTextColor("rgb(0, 255, 255)");
         internals.settings.setTextTrackTextSize("14px");
         internals.settings.setTextTrackWindowColor("rgba(0, 0, 0, 0.8)");
-        internals.settings.setTextTrackWindowPadding("5px");
         var video2 = addVideoTo(container);
         video2.oncanplaythrough = t.step_func_done(function() {
             var displayTree = textTrackCueElementByIndex(video2, 0);
diff --git a/third_party/blink/web_tests/media/track/track-cue-rendering-negative-line-numbers.html b/third_party/blink/web_tests/media/track/track-cue-rendering-negative-line-numbers.html
new file mode 100644
index 0000000..4c3a1dd2
--- /dev/null
+++ b/third_party/blink/web_tests/media/track/track-cue-rendering-negative-line-numbers.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../media-controls.js"></script>
+<style>
+::cue { font-size: 24px; }
+</style>
+<video src="../content/test.ogv" width="640"></video>
+<script>
+
+function animationFrame() {
+  return new Promise(resolve => { requestAnimationFrame(resolve); });
+}
+
+promise_test(async () => {
+  let v = document.querySelector('video');
+  let track = v.addTextTrack('subtitles', 'label', 'en');
+  track.mode = 'showing';
+  let cue0 = new VTTCue(1, 60, 'First subtitle');
+  cue0.line = -3;
+  track.addCue(cue0);
+  let cue1 = new VTTCue(1, 60, 'Second subtitle');
+  cue1.line = -2;
+  track.addCue(cue1);
+  let cue2 = new VTTCue(1, 60, 'Third subtitle');
+  cue2.line = -1;
+  track.addCue(cue2);
+
+  v.currentTime = 3;
+  await new Promise(resolve => { v.addEventListener('seeked', resolve, {once:true}); });
+  v.controls = false;
+  await animationFrame();
+  await animationFrame();
+  // Now cues are shown.
+  let top0 = textTrackCueElementByIndex(v, 0).offsetTop;
+  let top1 = textTrackCueElementByIndex(v, 1).offsetTop;
+  let top2 = textTrackCueElementByIndex(v, 2).offsetTop;
+  assert_true(top0<top1, 'subtitle 1 is above subtitle 2');
+  assert_true(top1<top2, 'subtitle 2 is above subtitle 3');
+}, 'Cues with negative line numbers should be displayed in order');
+</script>
diff --git a/third_party/blink/web_tests/paint/background/zoomed-inset-shadow-expected.html b/third_party/blink/web_tests/paint/background/zoomed-inset-shadow-expected.html
new file mode 100644
index 0000000..4f7d73ff
--- /dev/null
+++ b/third_party/blink/web_tests/paint/background/zoomed-inset-shadow-expected.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+.test {
+  width: 14px;
+  height: 14px;
+  background: green;
+}
+</style>
+<div class="test"></div>
+<div class="test" style="zoom: 1.1"></div>
+<div class="test" style="zoom: 1.218"></div>
+<div class="test" style="zoom: 1.337"></div>
+<div class="test" style="zoom: 3.122"></div>
diff --git a/third_party/blink/web_tests/paint/background/zoomed-inset-shadow.html b/third_party/blink/web_tests/paint/background/zoomed-inset-shadow.html
new file mode 100644
index 0000000..4976401
--- /dev/null
+++ b/third_party/blink/web_tests/paint/background/zoomed-inset-shadow.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>For crbug.com/1347097</title>
+<!-- This is not a WPT test because 'zoom' is not a standard CSS property. -->
+<style>
+.test {
+  width: 14px;
+  height: 14px;
+  background: red;
+  box-shadow: inset 16px 0 green;
+}
+</style>
+<div class="test"></div>
+<div class="test" style="zoom: 1.1"></div>
+<div class="test" style="zoom: 1.218"></div>
+<div class="test" style="zoom: 1.337"></div>
+<div class="test" style="zoom: 3.122"></div>
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni
index e0b93a4..57f77f6 100644
--- a/third_party/boringssl/BUILD.generated.gni
+++ b/third_party/boringssl/BUILD.generated.gni
@@ -29,13 +29,13 @@
   "src/crypto/asn1/f_int.c",
   "src/crypto/asn1/f_string.c",
   "src/crypto/asn1/internal.h",
+  "src/crypto/asn1/posix_time.c",
   "src/crypto/asn1/tasn_dec.c",
   "src/crypto/asn1/tasn_enc.c",
   "src/crypto/asn1/tasn_fre.c",
   "src/crypto/asn1/tasn_new.c",
   "src/crypto/asn1/tasn_typ.c",
   "src/crypto/asn1/tasn_utl.c",
-  "src/crypto/asn1/time_support.c",
   "src/crypto/base64/base64.c",
   "src/crypto/bio/bio.c",
   "src/crypto/bio/bio_mem.c",
@@ -312,6 +312,7 @@
   "src/include/openssl/conf.h",
   "src/include/openssl/cpu.h",
   "src/include/openssl/crypto.h",
+  "src/include/openssl/ctrdrbg.h",
   "src/include/openssl/curve25519.h",
   "src/include/openssl/des.h",
   "src/include/openssl/dh.h",
diff --git a/third_party/boringssl/apple-aarch64/crypto/fipsmodule/p256-armv8-asm.S b/third_party/boringssl/apple-aarch64/crypto/fipsmodule/p256-armv8-asm.S
index 0b655fc1..7a5202dd 100644
--- a/third_party/boringssl/apple-aarch64/crypto/fipsmodule/p256-armv8-asm.S
+++ b/third_party/boringssl/apple-aarch64/crypto/fipsmodule/p256-armv8-asm.S
@@ -31,58 +31,6 @@
 .byte	69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 
-// void	ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	_ecp_nistz256_to_mont
-.private_extern	_ecp_nistz256_to_mont
-
-.align	6
-_ecp_nistz256_to_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	ldr	x3,LRR		// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,Lpoly+8
-	ldr	x13,Lpoly+24
-	adr	x2,LRR		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-
-
-// void	ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	_ecp_nistz256_from_mont
-.private_extern	_ecp_nistz256_from_mont
-
-.align	4
-_ecp_nistz256_from_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	mov	x3,#1			// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,Lpoly+8
-	ldr	x13,Lpoly+24
-	adr	x2,Lone		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-
-
 // void	ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
 //					     const BN_ULONG x2[4]);
 .globl	_ecp_nistz256_mul_mont
diff --git a/third_party/boringssl/err_data.c b/third_party/boringssl/err_data.c
index 04b265d..7991be6 100644
--- a/third_party/boringssl/err_data.c
+++ b/third_party/boringssl/err_data.c
@@ -16,43 +16,43 @@
 
 #include <openssl/base.h>
 #include <openssl/err.h>
-#include <openssl/type_check.h>
 
+#include <assert.h>
 
-OPENSSL_STATIC_ASSERT(ERR_LIB_NONE == 1, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_SYS == 2, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_BN == 3, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_RSA == 4, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_DH == 5, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_EVP == 6, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_BUF == 7, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_OBJ == 8, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_PEM == 9, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_DSA == 10, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_X509 == 11, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_ASN1 == 12, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_CONF == 13, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_CRYPTO == 14, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_EC == 15, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_SSL == 16, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_BIO == 17, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS7 == 18, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_PKCS8 == 19, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_X509V3 == 20, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_RAND == 21, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_ENGINE == 22, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_OCSP == 23, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_UI == 24, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_COMP == 25, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_ECDSA == 26, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_ECDH == 27, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_HMAC == 28, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_DIGEST == 29, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_CIPHER == 30, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_HKDF == 31, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_TRUST_TOKEN == 32, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_LIB_USER == 33, "library value changed");
-OPENSSL_STATIC_ASSERT(ERR_NUM_LIBS == 34, "number of libraries changed");
+static_assert(ERR_LIB_NONE == 1, "library value changed");
+static_assert(ERR_LIB_SYS == 2, "library value changed");
+static_assert(ERR_LIB_BN == 3, "library value changed");
+static_assert(ERR_LIB_RSA == 4, "library value changed");
+static_assert(ERR_LIB_DH == 5, "library value changed");
+static_assert(ERR_LIB_EVP == 6, "library value changed");
+static_assert(ERR_LIB_BUF == 7, "library value changed");
+static_assert(ERR_LIB_OBJ == 8, "library value changed");
+static_assert(ERR_LIB_PEM == 9, "library value changed");
+static_assert(ERR_LIB_DSA == 10, "library value changed");
+static_assert(ERR_LIB_X509 == 11, "library value changed");
+static_assert(ERR_LIB_ASN1 == 12, "library value changed");
+static_assert(ERR_LIB_CONF == 13, "library value changed");
+static_assert(ERR_LIB_CRYPTO == 14, "library value changed");
+static_assert(ERR_LIB_EC == 15, "library value changed");
+static_assert(ERR_LIB_SSL == 16, "library value changed");
+static_assert(ERR_LIB_BIO == 17, "library value changed");
+static_assert(ERR_LIB_PKCS7 == 18, "library value changed");
+static_assert(ERR_LIB_PKCS8 == 19, "library value changed");
+static_assert(ERR_LIB_X509V3 == 20, "library value changed");
+static_assert(ERR_LIB_RAND == 21, "library value changed");
+static_assert(ERR_LIB_ENGINE == 22, "library value changed");
+static_assert(ERR_LIB_OCSP == 23, "library value changed");
+static_assert(ERR_LIB_UI == 24, "library value changed");
+static_assert(ERR_LIB_COMP == 25, "library value changed");
+static_assert(ERR_LIB_ECDSA == 26, "library value changed");
+static_assert(ERR_LIB_ECDH == 27, "library value changed");
+static_assert(ERR_LIB_HMAC == 28, "library value changed");
+static_assert(ERR_LIB_DIGEST == 29, "library value changed");
+static_assert(ERR_LIB_CIPHER == 30, "library value changed");
+static_assert(ERR_LIB_HKDF == 31, "library value changed");
+static_assert(ERR_LIB_TRUST_TOKEN == 32, "library value changed");
+static_assert(ERR_LIB_USER == 33, "library value changed");
+static_assert(ERR_NUM_LIBS == 34, "number of libraries changed");
 
 const uint32_t kOpenSSLReasonValues[] = {
     0xc320885,
diff --git a/third_party/boringssl/linux-aarch64/crypto/fipsmodule/p256-armv8-asm.S b/third_party/boringssl/linux-aarch64/crypto/fipsmodule/p256-armv8-asm.S
index 2106b85..3efcccb6 100644
--- a/third_party/boringssl/linux-aarch64/crypto/fipsmodule/p256-armv8-asm.S
+++ b/third_party/boringssl/linux-aarch64/crypto/fipsmodule/p256-armv8-asm.S
@@ -32,58 +32,6 @@
 .byte	69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 
-// void	ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	ecp_nistz256_to_mont
-.hidden	ecp_nistz256_to_mont
-.type	ecp_nistz256_to_mont,%function
-.align	6
-ecp_nistz256_to_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	ldr	x3,.LRR		// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,.Lpoly+8
-	ldr	x13,.Lpoly+24
-	adr	x2,.LRR		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-.size	ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-
-// void	ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	ecp_nistz256_from_mont
-.hidden	ecp_nistz256_from_mont
-.type	ecp_nistz256_from_mont,%function
-.align	4
-ecp_nistz256_from_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	mov	x3,#1			// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,.Lpoly+8
-	ldr	x13,.Lpoly+24
-	adr	x2,.Lone		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-
 // void	ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
 //					     const BN_ULONG x2[4]);
 .globl	ecp_nistz256_mul_mont
diff --git a/third_party/boringssl/win-aarch64/crypto/fipsmodule/p256-armv8-asm.S b/third_party/boringssl/win-aarch64/crypto/fipsmodule/p256-armv8-asm.S
index 4ebf3ab..cfffc0d 100644
--- a/third_party/boringssl/win-aarch64/crypto/fipsmodule/p256-armv8-asm.S
+++ b/third_party/boringssl/win-aarch64/crypto/fipsmodule/p256-armv8-asm.S
@@ -32,62 +32,6 @@
 .byte	69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 
-// void	ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	ecp_nistz256_to_mont
-
-.def ecp_nistz256_to_mont
-   .type 32
-.endef
-.align	6
-ecp_nistz256_to_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	ldr	x3,LRR		// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,Lpoly+8
-	ldr	x13,Lpoly+24
-	adr	x2,LRR		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-
-
-// void	ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-.globl	ecp_nistz256_from_mont
-
-.def ecp_nistz256_from_mont
-   .type 32
-.endef
-.align	4
-ecp_nistz256_from_mont:
-	AARCH64_SIGN_LINK_REGISTER
-	stp	x29,x30,[sp,#-32]!
-	add	x29,sp,#0
-	stp	x19,x20,[sp,#16]
-
-	mov	x3,#1			// bp[0]
-	ldp	x4,x5,[x1]
-	ldp	x6,x7,[x1,#16]
-	ldr	x12,Lpoly+8
-	ldr	x13,Lpoly+24
-	adr	x2,Lone		// &bp[0]
-
-	bl	__ecp_nistz256_mul_mont
-
-	ldp	x19,x20,[sp,#16]
-	ldp	x29,x30,[sp],#32
-	AARCH64_VALIDATE_LINK_REGISTER
-	ret
-
-
 // void	ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
 //					     const BN_ULONG x2[4]);
 .globl	ecp_nistz256_mul_mont
diff --git a/third_party/ipcz/src/remote_portal_test.cc b/third_party/ipcz/src/remote_portal_test.cc
index b941e13c..798fdfe9 100644
--- a/third_party/ipcz/src/remote_portal_test.cc
+++ b/third_party/ipcz/src/remote_portal_test.cc
@@ -335,7 +335,12 @@
   CloseAll({p, b});
 }
 
-TEST_P(RemotePortalTest, DisconnectThroughProxy) {
+#if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER)
+#define MAYBE_DisconnectThroughProxy DISABLED_DisconnectThroughProxy
+#else
+#define MAYBE_DisconnectThroughProxy DisconnectThroughProxy
+#endif
+TEST_P(RemotePortalTest, MAYBE_DisconnectThroughProxy) {
   // Exercises node disconnection. Namely if portals on nodes 1 and 3 are
   // connected via proxy on node 2, and node 3 disappears, node 1's portal
   // should observe peer closure.
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium
index 18b19f6f..0e4d643b 100644
--- a/third_party/nearby/README.chromium
+++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
 Name: Nearby Connections Library
 Short Name: Nearby
 URL: https://github.com/google/nearby
-Version: a732616a979b6761100dd53949eed4fc4070a93f
+Version: 319e5abea448dccff02541d83f1816e0e5a8a8f5
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/tools/android/avd/proto/generic_android33.textpb b/tools/android/avd/proto/generic_android33.textpb
new file mode 100644
index 0000000..728dcc3
--- /dev/null
+++ b/tools/android/avd/proto/generic_android33.textpb
@@ -0,0 +1,25 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Configuration for a generic x86_64 android-13 AVD (userdebug build).
+
+emulator_package {
+  package_name: "chromium/third_party/android_sdk/public/emulator"
+  version: "9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC"  # 31.2.10
+  dest_path: "generic_android33"
+}
+
+system_image_package {
+  package_name: "chromium/third_party/android_sdk/public/system-images/android-33/google_apis/x86_64"
+  version: "K_IMppJTdHCWfFNy_Yuf4PYAxVFEqDHq9ZcJX78yRM8C"  # beta 3
+  dest_path: "generic_android33"
+}
+system_image_name: "system-images;android-33;google_apis;x86_64"
+
+avd_package {
+  package_name: "chromium/third_party/android_sdk/public/avds/android-33/google_apis/x86_64"
+  version: "hnlA0LGr79H3hi0VeY7XkxxXX1z56vq2IWXTjinjIfYC"  # created in bb_id 8807005167166026577
+  dest_path: "generic_android33"
+}
+avd_name: "android_33_google_apis_x86_64"
diff --git a/tools/android/avd/proto/generic_playstore_android33.textpb b/tools/android/avd/proto/generic_playstore_android33.textpb
new file mode 100644
index 0000000..c0c1360
--- /dev/null
+++ b/tools/android/avd/proto/generic_playstore_android33.textpb
@@ -0,0 +1,25 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Configuration for a generic x86_64 android-13 AVD with playstore (user build).
+
+emulator_package {
+  package_name: "chromium/third_party/android_sdk/public/emulator"
+  version: "9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC"  # 31.2.10
+  dest_path: "generic_playstore_android33"
+}
+
+system_image_package {
+  package_name: "chromium/third_party/android_sdk/public/system-images/android-33/google_apis_playstore/x86_64"
+  version: "ndvYifhxEbUfsJ0FagczmGFFLE0Lp9ZxBif9P8seZS8C"  # beta 3
+  dest_path: "generic_playstore_android33"
+}
+system_image_name: "system-images;android-33;google_apis_playstore;x86_64"
+
+avd_package {
+  package_name: "chromium/third_party/android_sdk/public/avds/android-33/google_apis_playstore/x86_64"
+  version: "iA0wPpkNQEYnBaNUBuT6ZT89WpP-dTdsWYxjWgAy8m8C"  # created in bb_id 8807005167166026577
+  dest_path: "generic_playstore_android33"
+}
+avd_name: "android_33_google_apis_playstore_x86_64"
diff --git a/tools/boilerplate.py b/tools/boilerplate.py
index 31dcba1..cafa438d6 100755
--- a/tools/boilerplate.py
+++ b/tools/boilerplate.py
@@ -17,8 +17,7 @@
 import sys
 
 LINES = [
-    'Copyright %d The Chromium Authors. All rights reserved.' %
-        date.today().year,
+    f'Copyright {date.today().year} The Chromium Authors.',
     'Use of this source code is governed by a BSD-style license that can be',
     'found in the LICENSE file.'
 ]
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py
index 16ee674..1a6c2699 100755
--- a/tools/clang/scripts/build.py
+++ b/tools/clang/scripts/build.py
@@ -678,13 +678,6 @@
     isysroot = subprocess.check_output(['xcrun', '--show-sdk-path'],
                                        universal_newlines=True).rstrip()
 
-    # clang only automatically links to libc++ when targeting OS X 10.9+, so
-    # add stdlib=libc++ explicitly so clang can run on OS X versions as old as
-    # 10.7.
-    cxxflags += ['-stdlib=libc++']
-    ldflags += ['-stdlib=libc++']
-
-
   # See https://crbug.com/1302636#c49 - #c56 -- intercepting crypt_r() does not
   # work with the sysroot for not fully understood reasons. Disable it.
   sanitizers_override = [
@@ -930,7 +923,7 @@
                 '-target', 'x86_64-unknown-unknown', '-O2', '-g', '-std=c++14',
                  '-fno-exceptions', '-fno-rtti', '-w', '-c', training_source]
     if sys.platform == 'darwin':
-      train_cmd.extend(['-stdlib=libc++', '-isysroot', isysroot])
+      train_cmd.extend(['-isysroot', isysroot])
     RunCommand(train_cmd, msvc_arch='x64')
 
     # Merge profiles.
@@ -940,7 +933,7 @@
                                        '*.profraw')), msvc_arch='x64')
     print('Profile generated.')
 
-  deployment_target = '10.7'
+  deployment_target = '10.12'
 
   # If building at head, define a macro that plugins can use for #ifdefing
   # out code that builds at head, but not at CLANG_REVISION or vice versa.
@@ -1057,7 +1050,7 @@
          ]))
   elif sys.platform == 'darwin':
     compiler_rt_args = [
-        'SANITIZER_MIN_OSX_VERSION=10.7',
+        'SANITIZER_MIN_OSX_VERSION=' + deployment_target,
         'COMPILER_RT_ENABLE_MACCATALYST=ON',
         'COMPILER_RT_ENABLE_IOS=ON',
         'COMPILER_RT_ENABLE_WATCHOS=OFF',
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index faf7ec7..6350371 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -36,7 +36,7 @@
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
 CLANG_REVISION = 'llvmorg-16-init-572-gdde41c6c'
-CLANG_SUB_REVISION = 2
+CLANG_SUB_REVISION = 3
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '16.0.0'
diff --git a/tools/code_coverage/create_js_source_maps/create_js_source_maps.gni b/tools/code_coverage/create_js_source_maps/create_js_source_maps.gni
index 4ecd411..11382b4 100644
--- a/tools/code_coverage/create_js_source_maps/create_js_source_maps.gni
+++ b/tools/code_coverage/create_js_source_maps/create_js_source_maps.gni
@@ -21,7 +21,8 @@
                            ])
     script =
         "//tools/code_coverage/create_js_source_maps/create_js_source_maps.py"
-    args = [ "--sources" ] + rebase_path(invoker.sources, root_out_dir) +
+    args = [ "--originals" ] + rebase_path(invoker.originals, root_out_dir) +
+           [ "--sources" ] + rebase_path(invoker.sources, root_out_dir) +
            [ "--outputs" ] + rebase_path(invoker.outputs, root_out_dir)
     inputs = [
       "//tools/code_coverage/create_js_source_maps/create_js_source_maps.js",
diff --git a/tools/code_coverage/create_js_source_maps/create_js_source_maps.js b/tools/code_coverage/create_js_source_maps/create_js_source_maps.js
index 3136b1e91..880ab38f 100644
--- a/tools/code_coverage/create_js_source_maps/create_js_source_maps.js
+++ b/tools/code_coverage/create_js_source_maps/create_js_source_maps.js
@@ -56,6 +56,7 @@
  * Processes one processed TypeScript or JavaScript file and produces one
  * source map file / appends a source map.
  *
+ * @param {string} originalFileName Original path of `inputFileName`.
  * @param {string} inputFileName The TypeScript or JavaScript file to read from.
  * @param {string} outputFileName If `inlineSourcemaps`, the output TypeScript
  *                                or JavaScript file with the append source map.
@@ -66,10 +67,10 @@
  *                                   creating standalone map file.
  */
 function processOneFile(
-    inputFileName, outputFileName, verbose, inlineSourcemaps) {
+    originalFileName, inputFileName, outputFileName, verbose,
+    inlineSourcemaps) {
   const inputFile = fs.readFileSync(inputFileName, 'utf8');
   const inputLines = inputFile.split('\n');
-  const inputFileBaseName = path.basename(inputFileName);
   const map = new SourceMapGenerator();
 
   let originalLine = 0;
@@ -81,7 +82,7 @@
 
     // Add to sourcemap before looking for removal comments. The beginning of
     // the generated line came from the parts before the removal comment.
-    addMapping(map, inputFileBaseName, originalLine, generatedLine, verbose);
+    addMapping(map, originalFileName, originalLine, generatedLine, verbose);
 
     for (const removal of line.matchAll(GRIT_REMOVED_LINES_REGEX)) {
       const removedLines = Number.parseInt(removal[1], 10);
@@ -117,12 +118,15 @@
     help: 'Copies contents of input to output and appends inline source maps',
     action: 'storeTrue',
   });
+  parser.addArgument('original', {help: 'Original file name', action: 'store'});
   parser.addArgument('input', {help: 'Input file name', action: 'store'});
   parser.addArgument('output', {help: 'Output file name', action: 'store'});
 
   const argv = parser.parseArgs();
 
-  processOneFile(argv.input, argv.output, argv.verbose, argv.inline_sourcemaps);
+  processOneFile(
+      argv.original, argv.input, argv.output, argv.verbose,
+      argv.inline_sourcemaps);
 }
 
 main();
diff --git a/tools/code_coverage/create_js_source_maps/create_js_source_maps.py b/tools/code_coverage/create_js_source_maps/create_js_source_maps.py
index c33b9d3..1b35e118 100755
--- a/tools/code_coverage/create_js_source_maps/create_js_source_maps.py
+++ b/tools/code_coverage/create_js_source_maps/create_js_source_maps.py
@@ -17,20 +17,24 @@
 
 def main(argv):
   parser = argparse.ArgumentParser()
+  parser.add_argument('--originals', required=True, nargs="*")
   parser.add_argument('--sources', required=True, nargs="*")
   parser.add_argument('--outputs', required=True, nargs="*")
   parser.add_argument('--inline-sourcemaps', action='store_true')
   args = parser.parse_args(argv)
 
-  for source_file, output_file in zip(args.sources, args.outputs):
+  for original_file, source_file, output_file in zip(args.originals,
+                                                     args.sources,
+                                                     args.outputs):
     # Invokes "node create_js_source_maps.js (args)""
     # We can't use third_party/node/node.py directly from the gni template
     # because we don't have a good way to specify the path to
     # create_js_source_maps.js in a gni template.
     # TODO(crbug.com/1337530): Launching node is expensive. Instead, update the
     # JS script to accept multiple input/output files and do only one node run.
-    node.RunNode([str(_SOURCE_MAP_CREATOR), source_file, output_file] +
-                 (['--inline-sourcemaps'] if args.inline_sourcemaps else []))
+    node.RunNode(
+        [str(_SOURCE_MAP_CREATOR), original_file, source_file, output_file] +
+        (['--inline-sourcemaps'] if args.inline_sourcemaps else []))
 
 
 if __name__ == '__main__':
diff --git a/tools/code_coverage/create_js_source_maps/test/create_js_source_maps_test.py b/tools/code_coverage/create_js_source_maps/test/create_js_source_maps_test.py
index c2f6c9c..df0198a 100755
--- a/tools/code_coverage/create_js_source_maps/test/create_js_source_maps_test.py
+++ b/tools/code_coverage/create_js_source_maps/test/create_js_source_maps_test.py
@@ -86,9 +86,11 @@
                                                  suffix=".js")
     os.write(input_fd, file_after_preprocess)
     os.close(input_fd)
+    original_file_name = "input.js"
     output_file_name = input_file_name + ".out"
     node.RunNode([
         str(_SOURCE_MAP_PROCESSOR),
+        original_file_name,
         input_file_name,
         output_file_name,
     ] + (["--inline-sourcemaps"] if inline_sourcemap else []))
@@ -109,6 +111,8 @@
       with open(output_file_name) as map_file:
         source_map = map_file.read()
 
+    self.assertEqual(original_file_name, json.loads(source_map)['sources'][0])
+
     # Check mappings:
     # Line 1 is before any removed lines, so it still maps to line 1
     line, column = self._translate(source_map, 1, 2)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 58ce65cc..517d6b4 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -133,6 +133,7 @@
       'android-marshmallow-x86-fyi-rel-reviver': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_google_reclient',
       'android-nougat-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
       'android-pie-arm64-wpt-rel-non-cq': 'android_release_bot_minimal_symbols_arm64_webview_monochrome_reclient',
+      'android-pie-x86-fyi-rel-reviver': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
       'android-weblayer-pie-x86-wpt-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
       'android-weblayer-pie-x86-wpt-smoketest': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
       'android-weblayer-with-aosp-webview-x86-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_resource_allowlisting_disable_proguard_chrome_google_reclient',
@@ -416,8 +417,8 @@
       'ios15-beta-simulator': 'ios_simulator_debug_static_bot_xctest',
       'ios15-sdk-device': 'ios_device_release_static_bot_xctest',
       'ios15-sdk-simulator': 'ios_simulator_debug_static_bot_xctest',
-      'ios16-beta-simulator': 'ios_simulator_debug_static_bot_xctest_arm64',
-      'ios16-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_arm64_no_lld_treat_warnings_as_errors',
+      'ios16-beta-simulator': 'ios_simulator_debug_static_bot_xctest',
+      'ios16-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_x64_no_lld_treat_warnings_as_errors',
       'lacros-amd64-generic-rel (goma cache silo)': 'chromeos_amd64-generic_lacros_rel',
       'lacros-amd64-generic-rel (reclient)': 'chromeos_amd64-generic-vm_lacros_rel_reclient',
       'lacros-amd64-generic-rel-fyi': 'chromeos_amd64-generic_lacros_rel_reclient',
@@ -986,6 +987,7 @@
       'android-pie-arm64-dbg': 'android_debug_trybot_arm64',
       'android-pie-arm64-rel': 'android_release_trybot_arm64_webview_monochrome_expectations_fastbuild',
       'android-pie-arm64-wpt-rel-non-cq': 'android_release_trybot_arm64_webview_monochrome',
+      'android-pie-x86-fyi-rel-reviver': 'android_release_trybot_x86_fastbuild_webview_monochrome',
       'android-pie-x86-rel': 'android_release_trybot_x86_fastbuild_webview_monochrome',
       'android-weblayer-10-x86-rel-tests': 'android_release_trybot_minimal_symbols_x86_fastbuild_disable_proguard_chrome_google',
       'android-weblayer-marshmallow-x86-rel-tests': 'android_release_trybot_minimal_symbols_x86_fastbuild_disable_proguard_chrome_google',
@@ -1223,8 +1225,8 @@
       'ios-simulator-rts': 'ios_simulator_code_coverage_partial_instrumentation_xctest',
       'ios15-beta-simulator': 'ios_simulator_debug_static_bot_xctest',
       'ios15-sdk-simulator': 'ios_simulator_debug_static_bot_xctest',
-      'ios16-beta-simulator': 'ios_simulator_debug_static_bot_xctest_arm64',
-      'ios16-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_arm64_no_lld_treat_warnings_as_errors',
+      'ios16-beta-simulator': 'ios_simulator_debug_static_bot_xctest',
+      'ios16-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_x64_no_lld_treat_warnings_as_errors',
       'mac-arm64-on-arm64-rel': 'mac_arm64_release_trybot',
       'mac-builder-next-rel': 'mac_arm64_gpu_tests_release_bot_minimal_symbols_no_nacl',
       'mac-fieldtrial-rel': 'mac_arm64_gpu_tests_release_bot_minimal_symbols_no_nacl',
@@ -2937,10 +2939,6 @@
         'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_arm64', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
-    'ios_simulator_debug_static_bot_xctest_arm64_no_lld_treat_warnings_as_errors': [
-        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_arm64', 'xctest', 'ios_disable_xcode_project_generation', 'no_lld', 'treat_warnings_as_errors'
-    ],
-
     'ios_simulator_debug_static_bot_xctest_no_lld': [
         'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation', 'no_lld',
     ],
@@ -2949,6 +2947,10 @@
         'debug_static_bot_reclient', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation',
     ],
 
+    'ios_simulator_debug_static_bot_xctest_x64_no_lld_treat_warnings_as_errors': [
+        'debug_static_bot', 'ios', 'ios_simulator', 'ios_cpu_x64', 'xctest', 'ios_disable_xcode_project_generation', 'no_lld', 'treat_warnings_as_errors'
+    ],
+
     'ios_simulator_release_static_asan_bot_xctest': [
         'ios', 'ios_simulator', 'ios_cpu_x64', 'release_bot', 'asan', 'xctest', 'ios_disable_xcode_project_generation',
     ],
diff --git a/tools/mb/mb_config_expectations/chromium.android.fyi.json b/tools/mb/mb_config_expectations/chromium.android.fyi.json
index 85b6ace..c860b12 100644
--- a/tools/mb/mb_config_expectations/chromium.android.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.android.fyi.json
@@ -137,6 +137,23 @@
       "use_remoteexec": true
     }
   },
+  "android-pie-x86-fyi-rel-reviver": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "disable_android_lint": true,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "strip_debug_info": true,
+      "symbol_level": 1,
+      "system_webview_package_name": "com.google.android.apps.chrome",
+      "target_cpu": "x86",
+      "target_os": "android",
+      "use_errorprone_java_compiler": false,
+      "use_remoteexec": true
+    }
+  },
   "android-weblayer-pie-x86-wpt-fyi-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 0f37ca0..f8d31377 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -1044,7 +1044,7 @@
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
-      "target_cpu": "arm64",
+      "target_cpu": "x64",
       "target_environment": "simulator",
       "target_os": "ios",
       "use_goma": true
@@ -1057,7 +1057,7 @@
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
-      "target_cpu": "arm64",
+      "target_cpu": "x64",
       "target_environment": "simulator",
       "target_os": "ios",
       "treat_warnings_as_errors": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index 8b289be..12d944cc 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -779,6 +779,23 @@
       "use_goma": true
     }
   },
+  "android-pie-x86-fyi-rel-reviver": {
+    "gn_args": {
+      "dcheck_always_on": true,
+      "disable_android_lint": true,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "strip_debug_info": true,
+      "symbol_level": 0,
+      "system_webview_package_name": "com.google.android.apps.chrome",
+      "target_cpu": "x86",
+      "target_os": "android",
+      "use_errorprone_java_compiler": false,
+      "use_goma": true
+    }
+  },
   "android-pie-x86-rel": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index b5ea7d67..bfc8dfa0 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -440,7 +440,7 @@
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
-      "target_cpu": "arm64",
+      "target_cpu": "x64",
       "target_environment": "simulator",
       "target_os": "ios",
       "use_goma": true
@@ -453,7 +453,7 @@
       "is_component_build": false,
       "is_debug": true,
       "symbol_level": 1,
-      "target_cpu": "arm64",
+      "target_cpu": "x64",
       "target_environment": "simulator",
       "target_os": "ios",
       "treat_warnings_as_errors": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index cbdd7f0..bcf5c44d 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -2303,6 +2303,8 @@
   <int value="262158" label="4.14"/>
   <int value="262163" label="4.19"/>
   <int value="327684" label="5.4"/>
+  <int value="327690" label="5.10"/>
+  <int value="327695" label="5.15"/>
 </enum>
 
 <enum name="AndroidManageSpaceButton">
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 7283231..72168b6 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -938,9 +938,12 @@
 </histogram>
 
 <histogram name="IOS.MetricKit.ApplicationHangTime" units="ms"
-    expires_after="2023-01-15">
+    expires_after="never">
+<!-- expires-never: guiding metric (internal: go/chrome-browser-guiding-metrics) -->
+
   <owner>justincohen@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
+  <owner>chrome-analysis-team@google.com</owner>
   <summary>
     The durations of time in which the app is too busy to handle user input
     responsively. This covers all forms of user input, including all touch
@@ -962,6 +965,9 @@
 
     Recorded only if user opted in for sharing diagnostic data on iOS device.
     Note: The date the data is reported is later than the day it account for.
+
+    This histogram is of special interest to the chrome-analysis-team@. Do not
+    change its semantics or retire it without talking to them first.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml
index d3df8200..d487f408 100644
--- a/tools/metrics/histograms/metadata/omnibox/histograms.xml
+++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -53,13 +53,13 @@
                synchronous. Logged exactly once per update; 0, 1, or multiple
                times per input. The count here will be the sum of the counts
                for the other 2 slices."/>
-  <variant name="Async"
+  <variant name=".Async"
       summary="This slice measures match changes between the last update for
                the current input, whether it be asynchronous or synchronous,
                and the current asynchronous, i.e. non-first, update of the
                current input. Logged exactly once per asynchronous update; 0,
                1, or multiple times per input."/>
-  <variant name="CrossInput"
+  <variant name=".CrossInput"
       summary="This slice measures match changes between the last update for
                the previous input, whether it be asynchronous or synchronous,
                and the synchronous, i.e. first, update of the current input.
@@ -988,7 +988,11 @@
 
     This histogram can be considered a boolean analogue to the
     Omnibox.MatchStability.Index.* histogram which tracks which matches changed.
+
+    {OmniboxAutocompleteUpdateSlice}
   </summary>
+  <token key="OmniboxAutocompleteUpdateSlice"
+      variants="OmniboxAutocompleteUpdateSlice"/>
 </histogram>
 
 <histogram
@@ -1038,7 +1042,11 @@
 
     There's the related Omnibox.MatchStability.InAnyPosition histogram for
     tracking whether any match changed per autocomplete update.
+
+    {OmniboxAutocompleteUpdateSlice}
   </summary>
+  <token key="OmniboxAutocompleteUpdateSlice"
+      variants="OmniboxAutocompleteUpdateSlice"/>
 </histogram>
 
 <histogram name="Omnibox.NumEvents" enum="UsedOmnibox"
diff --git a/tools/metrics/histograms/metadata/web_audio/histograms.xml b/tools/metrics/histograms/metadata/web_audio/histograms.xml
index 623aa5b..f3a7bc7 100644
--- a/tools/metrics/histograms/metadata/web_audio/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_audio/histograms.xml
@@ -67,10 +67,11 @@
 </histogram>
 
 <histogram name="WebAudio.AudioContext.CreateTime" units="ms"
-    expires_after="2022-08-12">
+    expires_after="2022-12-31">
   <owner>hongchan@chromium.org</owner>
   <owner>mjwilson@chromium.org</owner>
   <owner>cduvall@chromium.org</owner>
+  <owner>src/third_party/blink/renderer/modules/webaudio/OWNERS</owner>
   <summary>
     Measures the time it takes to create the AudioContext object. This is
     recorded every time an AudioContext is successfully created.
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index 91636c903..8ee8f7e 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1403,13 +1403,19 @@
   width: 16px;
 }
 
-body.files-ng .loading-indicator {
+.loading-indicator {
   left: calc(50% - 24px);
   position: absolute;
   right: calc(50% - 24px);
   top: 64px;
 }
 
+.list-view .loading-indicator {
+  /* The list view has a .table-header at the top, the top should also
+  cover that, hence the desired top plus the .table-header height. */
+  top: calc(64px + 57px);
+}
+
 @keyframes heightAnimation {
   0% {
     display: flex;
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index 2ca6b93..183f490 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -749,14 +749,31 @@
     }
 
     // Clear the table, and start scanning.
-    dispatchSimpleEvent(this, 'scan-started');
     fileList.splice(0, fileList.length);
+    dispatchSimpleEvent(this, 'scan-started');
     this.scan_(
         this.currentDirContents_, false, true, onDone, onFailed, onUpdated,
         onCancelled);
   }
 
   /**
+   * Similar to clearAndScan_() but instead of passing a `newDirContents`, it
+   * uses the `currentDirContents_`.
+   */
+  clearCurrentDirAndScan() {
+    const sequence = ++this.changeDirectorySequence_;
+    this.directoryChangeQueue_.run(callback => {
+      if (this.changeDirectorySequence_ !== sequence) {
+        callback();
+        return;
+      }
+      const newDirContents = this.createDirectoryContents_(
+          this.currentFileListContext_, assert(this.getCurrentDirEntry()));
+      this.clearAndScan_(newDirContents, callback);
+    });
+  }
+
+  /**
    * Adds/removes/updates items of file list.
    * @param {Array<Entry>} changedEntries Entries of updated/added files.
    * @param {Array<string>} removedUrls URLs of removed files.
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js
index 0eeb2a1b..8572273c 100644
--- a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller.js
@@ -249,9 +249,8 @@
     if (isButtonActive) {
       this.allFilterButton_.focus();
     }
-    // Refresh current directory with the updated Recent setting.
-    // We don't need to invalidate the cached metadata for this rescan.
-    this.directoryModel_.rescan(false);
+    // Clear and scan the current directory with the updated Recent setting.
+    this.directoryModel_.clearCurrentDirAndScan();
     this.speakA11yMessage(currentFilter, newFilter);
     this.recordFileTypeFilterUMA_(newFilter);
   }
diff --git a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js
index 4e94395..6849e5e 100644
--- a/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/file_type_filters_controller_unittest.js
@@ -93,11 +93,11 @@
       super();
 
       this.currentDirEntry = null;
-      window.isRescanCalled = false;
+      window.isScanCalled = false;
     }
 
-    rescan(refresh) {
-      window.isRescanCalled = true;
+    clearCurrentDirAndScan() {
+      window.isScanCalled = true;
     }
 
     changeDirectoryEntry(dirEntry) {
@@ -296,40 +296,40 @@
   assertEquals(
       recentEntry.recentFileType,
       chrome.fileManagerPrivate.RecentFileType.AUDIO);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 
   // Clicking an active button will trigger a scan for "All".
   buttons[1].click();
   assertEquals(
       recentEntry.recentFileType, chrome.fileManagerPrivate.RecentFileType.ALL);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 
   buttons[2].click();
   assertEquals(
       recentEntry.recentFileType,
       chrome.fileManagerPrivate.RecentFileType.DOCUMENT);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 
   buttons[3].click();
   assertEquals(
       recentEntry.recentFileType,
       chrome.fileManagerPrivate.RecentFileType.IMAGE);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 
   buttons[4].click();
   assertEquals(
       recentEntry.recentFileType,
       chrome.fileManagerPrivate.RecentFileType.VIDEO);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 
   buttons[0].click();
   assertEquals(
       recentEntry.recentFileType, chrome.fileManagerPrivate.RecentFileType.ALL);
-  assertTrue(window.isRescanCalled);
-  window.isRescanCalled = false;
+  assertTrue(window.isScanCalled);
+  window.isScanCalled = false;
 }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
index d2f458c..b33466f 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -876,7 +876,7 @@
     label.className = 'detail-name';
     label.appendChild(
         filelist.renderFileNameLabel(this.ownerDocument, entry, locationInfo));
-    if (locationInfo.isDriveBased) {
+    if (locationInfo && locationInfo.isDriveBased) {
       label.appendChild(filelist.renderPinned(this.ownerDocument));
     }
     const isDlpRestricted = !!metadata.isDlpRestricted;
diff --git a/ui/gfx/geometry/rect_f.cc b/ui/gfx/geometry/rect_f.cc
index c9084cf..1801ca1 100644
--- a/ui/gfx/geometry/rect_f.cc
+++ b/ui/gfx/geometry/rect_f.cc
@@ -8,6 +8,7 @@
 #include <limits>
 
 #include "base/check.h"
+#include "base/check_op.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
@@ -148,6 +149,18 @@
   float rb = std::max(bottom(), rect.bottom());
 
   SetRect(rx, ry, rr - rx, rb - ry);
+
+  // Due to floating errors, the new rect may not fully contain the original
+  // rects at the right/bottom side. Expand the rect in the case.
+  constexpr auto kFloatMax = std::numeric_limits<float>::max();
+  if (UNLIKELY(right() < rr && width() < kFloatMax)) {
+    set_width(std::nextafter(width(), kFloatMax));
+    DCHECK_GE(right(), rr);
+  }
+  if (UNLIKELY(bottom() < rb && height() < kFloatMax)) {
+    set_height(std::nextafter(height(), kFloatMax));
+    DCHECK_GE(bottom(), rb);
+  }
 }
 
 void RectF::Subtract(const RectF& rect) {
diff --git a/ui/gfx/geometry/rect_f_unittest.cc b/ui/gfx/geometry/rect_f_unittest.cc
index b30d275..b9eb3f5 100644
--- a/ui/gfx/geometry/rect_f_unittest.cc
+++ b/ui/gfx/geometry/rect_f_unittest.cc
@@ -159,6 +159,26 @@
                                         RectF(8.8f, 9.9f, 2.2f, 0)));
 }
 
+TEST(RectFTest, UnionEnsuresContainWithFloatingError) {
+  for (float f = 0.1f; f < 5; f += 0.1f) {
+    gfx::RectF r1(1, 2, 3, 4);
+    r1.Scale(f, f + 0.05f);
+    gfx::RectF r2 = r1 + gfx::Vector2dF(10.f + f, f - 10.f);
+    gfx::RectF r3 = gfx::UnionRects(r1, r2);
+    EXPECT_TRUE(r3.Contains(r1));
+    EXPECT_TRUE(r3.Contains(r2));
+  }
+}
+
+TEST(RectFTest, UnionMaxRects) {
+  constexpr float kMaxFloat = std::numeric_limits<float>::max();
+  constexpr float kMinFloat = std::numeric_limits<float>::min();
+  gfx::RectF r1(kMinFloat, 0, kMaxFloat, kMaxFloat);
+  gfx::RectF r2(0, kMinFloat, kMaxFloat, kMaxFloat);
+  // This should not trigger DCHECK failure.
+  r1.Union(r2);
+}
+
 TEST(RectFTest, CenterPoint) {
   PointF center;
 
diff --git a/ui/gfx/test/run_all_unittests.cc b/ui/gfx/test/run_all_unittests.cc
index a9121ce..5629a59 100644
--- a/ui/gfx/test/run_all_unittests.cc
+++ b/ui/gfx/test/run_all_unittests.cc
@@ -57,7 +57,7 @@
 #endif
 
 #if BUILDFLAG(IS_FUCHSIA)
-    skia::ConfigureTestFont();
+    skia::InitializeSkFontMgrForTest();
 #endif
 
     gfx::InitializeFonts();
diff --git a/ui/native_theme/caption_style.h b/ui/native_theme/caption_style.h
index d95f6f84..82732a5 100644
--- a/ui/native_theme/caption_style.h
+++ b/ui/native_theme/caption_style.h
@@ -42,7 +42,6 @@
   std::string font_family;
   std::string font_variant;
   std::string window_color;
-  std::string window_padding;
   std::string window_radius;
 };
 
diff --git a/ui/native_theme/caption_style_mac.mm b/ui/native_theme/caption_style_mac.mm
index 390eac6e..27cbbda 100644
--- a/ui/native_theme/caption_style_mac.mm
+++ b/ui/native_theme/caption_style_mac.mm
@@ -159,16 +159,6 @@
                               important);
 }
 
-// If the window is visible (its opacity is greater than 0), give it padding so
-// it surrounds the text track cue. If it is not visible, its padding should be
-// 0. Webkit uses 0.4em padding so we match that here.
-std::string GetMAWindowPaddingAsCSSNumberInEm() {
-  MACaptionAppearanceBehavior behavior;
-  float opacity = MACaptionAppearanceGetWindowOpacity(kUserDomain, &behavior);
-  bool important = behavior == kMACaptionAppearanceBehaviorUseValue;
-  return MaybeAddCSSImportant(opacity > 0 ? "0.4em" : "0em", important);
-}
-
 std::string GetMAWindowRadiusAsCSSNumberInPixels() {
   MACaptionAppearanceBehavior behavior;
   float radius =
@@ -191,7 +181,6 @@
   style.text_size = GetMATextScaleAsCSSPercent();
   style.text_shadow = GetMATextEdgeStyleAsCSSShadow();
   style.window_color = GetMAWindowColorAsCSSColor();
-  style.window_padding = GetMAWindowPaddingAsCSSNumberInEm();
   style.window_radius = GetMAWindowRadiusAsCSSNumberInPixels();
 
   GetMAFontAsCSSFontSpecifiers(&style.font_family, &style.font_variant);
diff --git a/ui/webui/resources/cr_elements/cr_tab_box/cr_tab_box.ts b/ui/webui/resources/cr_elements/cr_tab_box/cr_tab_box.ts
index 1d92acf..956b083 100644
--- a/ui/webui/resources/cr_elements/cr_tab_box/cr_tab_box.ts
+++ b/ui/webui/resources/cr_elements/cr_tab_box/cr_tab_box.ts
@@ -8,6 +8,12 @@
 
 import {getTemplate} from './cr_tab_box.html.js';
 
+declare global {
+  interface HTMLElementEventMap {
+    'selected-index-change': CustomEvent<number>;
+  }
+}
+
 export class CrTabBoxElement extends CustomElement {
   static override get template() {
     return getTemplate();
diff --git a/weblayer/browser/page_load_metrics_browsertest.cc b/weblayer/browser/page_load_metrics_browsertest.cc
index f6f7dc15..060d0a3 100644
--- a/weblayer/browser/page_load_metrics_browsertest.cc
+++ b/weblayer/browser/page_load_metrics_browsertest.cc
@@ -26,10 +26,22 @@
 
   // page_load_metrics::PageLoadMetricsObserver implementation:
 
-  // TODO(https://crbug.com/1317494): Audit and use appropriate policy.
   ObservePolicy OnFencedFramesStart(
       content::NavigationHandle* navigation_handle,
       const GURL& currently_committed_url) override {
+    // This class is only interested in events for outer-most frame that are
+    // forwarded by PageLoadTracker. So, this class doesn't need observer-level
+    // forwarding.
+    return STOP_OBSERVING;
+  }
+
+  PageLoadMetricsObserver::ObservePolicy OnPrerenderStart(
+      content::NavigationHandle* navigation_handle,
+      const GURL& currently_committed_url) override {
+    // Currently, prerendering is not enabled for WebLayer.
+    //
+    // TODO(https://crbug.com/1267224): If support prerendering, add callbacks
+    // and tests.
     return STOP_OBSERVING;
   }
 
diff --git a/weblayer/browser/page_load_metrics_observer_impl.cc b/weblayer/browser/page_load_metrics_observer_impl.cc
index fdaeaf8..48216ab 100644
--- a/weblayer/browser/page_load_metrics_observer_impl.cc
+++ b/weblayer/browser/page_load_metrics_observer_impl.cc
@@ -18,11 +18,24 @@
 
 namespace weblayer {
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 PageLoadMetricsObserverImpl::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // This class is only interested in events for outer-most frame that are
+  // forwarded by PageLoadTracker. So, this class doesn't need observer-level
+  // forwarding.
+  return STOP_OBSERVING;
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PageLoadMetricsObserverImpl::OnPrerenderStart(
+    content::NavigationHandle* navigation_handle,
+    const GURL& currently_committed_url) {
+  // Currently, prerendering is not enabled for WebLayer.
+  //
+  // TODO(https://crbug.com/1267224): If support prerendering, add callbacks,
+  // e.g. notification of activation_start.
   return STOP_OBSERVING;
 }
 
diff --git a/weblayer/browser/page_load_metrics_observer_impl.h b/weblayer/browser/page_load_metrics_observer_impl.h
index c6d94133..b23b030 100644
--- a/weblayer/browser/page_load_metrics_observer_impl.h
+++ b/weblayer/browser/page_load_metrics_observer_impl.h
@@ -19,6 +19,8 @@
   ObservePolicy OnFencedFramesStart(
       content::NavigationHandle* navigation_handle,
       const GURL& currently_committed_url) override;
+  ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle,
+                                 const GURL& currently_committed_url) override;
   ObservePolicy FlushMetricsOnAppEnterBackground(
       const page_load_metrics::mojom::PageLoadTiming& timing) override;
   ObservePolicy OnHidden(