diff --git a/.eslintrc.js b/.eslintrc.js
index 9b682b6..be406d5 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -87,7 +87,12 @@
         {
           selector: 'classMethod',
           format: ['camelCase'],
-          leadingUnderscore: 'allow',
+          modifiers: ['public'],
+        },
+        {
+          selector: 'classMethod',
+          format: ['camelCase'],
+          modifiers: ['private'],
           trailingUnderscore: 'allow',
         },
         {
diff --git a/BUILD.gn b/BUILD.gn
index 163bd31..6b95d21a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -18,7 +18,6 @@
 import("//build/gn_logs.gni")
 import("//build/util/generate_wrapper.gni")
 import("//chrome/browser/buildflags.gni")
-import("//chrome/browser/media/router/features.gni")
 import("//components/nacl/features.gni")
 import("//device/vr/buildflags/buildflags.gni")
 import("//extensions/buildflags/buildflags.gni")
@@ -234,10 +233,6 @@
     }
   }
 
-  if (enable_openscreen) {
-    deps += [ "//chrome/browser/media/router:openscreen_unittests" ]
-  }
-
   if (!is_ios) {
     deps += [
       "//google_apis/gcm:mcs_probe",
diff --git a/DEPS b/DEPS
index bc8c7634..727f7eae 100644
--- a/DEPS
+++ b/DEPS
@@ -280,15 +280,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': '79aaa7c4d2d2b896f72b92ad2ad4791e37fa4334',
+  'skia_revision': '008d60e58c9d9d7b11c0814b6a04e2dbd13050fb',
   # 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': 'dc48e6496209f29b87b58bbcd6a6ebfcc64eb0df',
+  'v8_revision': 'fee3847adc762bdd7bb8a0e48e06c3ccaa5efac5',
   # 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': '15376d4ec40a34d2f9347cffc156b2cef96906c2',
+  'angle_revision': '9ebc1b6ae421e9d56ce07ee6f699520bd76e9e97',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -351,7 +351,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': '0eef5371808c956e2dd8e438c511d2752cfeb73f',
+  'catapult_revision': '2b591cc800048d0e4f8d9e6a7222c54be4f45811',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -395,11 +395,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '2ae29830db8d1ec4cc0d7fa3e2c8d0bfe8f593fa',
+  'dawn_revision': '2032d034002a8002774a996b4707ca6b082949c6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'dad8fadd04563dbeb1cae44b4f2a164032e6dd3c',
+  'quiche_revision': 'd29a68fc287d148722cfd9d9312df0dba05e6902',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -463,7 +463,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       'b1269813eaf5b8ac78e35e45a0f7cc320bd3e7d6',
+  'libcxx_revision':       '1a637088a36d19d4ba0358c5e2994c3c9e024a62',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:e62d4e1938a45babc9afb6db543f388cd1802a52',
@@ -1145,7 +1145,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c5c48533cfdfe58302eb233f8d57e05aa559cd2a',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ecb22a6b70d5a44e3e9f7245211b9eac5ae9081a',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1299,7 +1299,7 @@
     Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '41cdffd71c9948f63c7ad36e1fb0ff519aa7a37e',
 
   'src/third_party/icu':
-    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '12de966fcbe1d1a48dba310aee63807856ffeee8',
+    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '1da917013f1e008f12e3e5d0853d889f893875ac',
 
   'src/third_party/icu4j': {
       'packages': [
@@ -1542,7 +1542,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9fcbb7415a3717c30e656811bc6509eee4d13040',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '66845965eea2742de82e11ca9467e53b01b78a31',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1673,7 +1673,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@1762849caed4eaf56fcb8b5b8af04b055a4b05f3',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@8b44f9a34e1f561d6a91bc80eed34f505eaf8a41',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1709,7 +1709,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'e58ed2132aa47ac110a4cce1763abfa34f4fa34e',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0cdb6c8d23c93ceef3b0f51611cb7e546e9b0fa5',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '1e9b6f7a6dbb5a3bb4c5e6472e599fb6577c9ef2',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '7ef4f514c51b6ed7050f08f76698e4e6a77949b3',
diff --git a/ash/clipboard/clipboard_history.cc b/ash/clipboard/clipboard_history.cc
index 176a1641..cace564 100644
--- a/ash/clipboard/clipboard_history.cc
+++ b/ash/clipboard/clipboard_history.cc
@@ -6,9 +6,13 @@
 
 #include "ash/clipboard/clipboard_history_util.h"
 #include "ash/clipboard/clipboard_nudge_controller.h"
+#include "ash/clipboard/scoped_clipboard_history_pause_impl.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_buffer.h"
+#include "ui/base/clipboard/clipboard_data.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
 #include "ui/base/clipboard/clipboard_non_backed.h"
 #include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
@@ -78,6 +82,7 @@
 
   auto removed = std::move(*iter);
   history_list_.erase(iter);
+  SyncClipboardToClipboardHistory();
   for (auto& observer : observers_)
     observer.OnClipboardHistoryItemRemoved(removed);
 }
@@ -89,17 +94,17 @@
   if (num_pause_ > 0)
     return;
 
+  // The clipboard may not exist in tests.
   auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread();
-  // Clipboard may not exist in tests.
   if (!clipboard)
     return;
 
   ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory);
   const auto* clipboard_data = clipboard->GetClipboardData(&data_dst);
   if (!clipboard_data) {
-    // `clipboard_data` is only empty when the Clipboard is cleared. This is
-    // done to prevent data leakage into or from locked forms(Locked Fullscreen
-    // state). Clear ClipboardHistory.
+    // `clipboard_data` is only empty when the clipboard is cleared. This is
+    // done to prevent data leakage into or from locked states (e.g., locked
+    // fullscreen). Clipboard history should also be cleared in this case.
     commit_data_weak_factory_.InvalidateWeakPtrs();
     Clear();
     return;
@@ -183,6 +188,32 @@
   return weak_factory_.GetWeakPtr();
 }
 
+void ClipboardHistory::SyncClipboardToClipboardHistory() {
+  // The clipboard may not exist in tests.
+  auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread();
+  if (!clipboard)
+    return;
+
+  ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory);
+  const auto* clipboard_data = clipboard->GetClipboardData(&data_dst);
+
+  // Only modify the clipboard if doing so would change its data, so as to avoid
+  // extraneous notifications to clipboard observers. If there is a change to
+  // make, pause clipboard history so that making the clipboard consistent with
+  // clipboard history does not cause clipboard history to update again.
+  ScopedClipboardHistoryPauseImpl scoped_pause(this);
+  if (history_list_.empty()) {
+    if (clipboard_data) {
+      static_cast<ui::Clipboard*>(clipboard)->Clear(
+          ui::ClipboardBuffer::kCopyPaste);
+    }
+  } else if (const auto& top_of_history_data = history_list_.front().data();
+             top_of_history_data != *clipboard_data) {
+    clipboard->WriteClipboardData(
+        std::make_unique<ui::ClipboardData>(top_of_history_data));
+  }
+}
+
 void ClipboardHistory::MaybeCommitData(ui::ClipboardData data) {
   if (!ClipboardHistoryUtil::IsSupported(data))
     return;
diff --git a/ash/clipboard/clipboard_history.h b/ash/clipboard/clipboard_history.h
index 78e7bd2..953e8956 100644
--- a/ash/clipboard/clipboard_history.h
+++ b/ash/clipboard/clipboard_history.h
@@ -72,6 +72,11 @@
   // `Resume()`.
   friend class ScopedClipboardHistoryPauseImpl;
 
+  // Ensures that the clipboard buffer contains the same data as the item at the
+  // top of clipboard history. If clipboard history is empty, then the clipboard
+  // is cleared.
+  void SyncClipboardToClipboardHistory();
+
   // Adds `data` to the top of the history list if `data` is supported by
   // clipboard history. If `data` is not supported, this method no-ops. If
   // `data` is already in the history list, `data` will be moved to the top of
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 258f16c..ae37e130 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -342,7 +342,7 @@
 
 // Enables or disables Crosh System Web App. When enabled, crosh (ChromeOS
 // Shell) will run as a tabbed System Web App rather than a normal browser tab.
-const base::Feature kCroshSWA{"CroshSWA", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kCroshSWA{"CroshSWA", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables upgrading the crostini container to debian bullseye.
 const base::Feature kCrostiniBullseyeUpgrade{"CrostiniBullseyeUpgrade",
@@ -1111,7 +1111,7 @@
 
 // If enabled, the new recommend apps screen is shown.
 const base::Feature kOobeNewRecommendApps{"OobeNewRecommendApps",
-                                          base::FEATURE_DISABLED_BY_DEFAULT};
+                                          base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Removes "Shut down" button from OOBE, except first login screen and
 // successful enrollment step.
diff --git a/ash/system/eche/eche_icon_loading_indicator_view_unittest.cc b/ash/system/eche/eche_icon_loading_indicator_view_unittest.cc
index 372c97d0..7ebb3a4f 100644
--- a/ash/system/eche/eche_icon_loading_indicator_view_unittest.cc
+++ b/ash/system/eche/eche_icon_loading_indicator_view_unittest.cc
@@ -4,11 +4,19 @@
 
 #include "ash/system/eche/eche_icon_loading_indicator_view.h"
 
+#include "ash/style/ash_color_provider.h"
 #include "ash/test/ash_test_base.h"
+#include "ui/gfx/canvas.h"
 #include "ui/views/controls/image_view.h"
 
 namespace ash {
 
+namespace {
+
+constexpr int kSizeInDip = 5;
+
+}  // namespace
+
 class EcheIconLoadingIndicatorViewTest : public AshTestBase {
  public:
   EcheIconLoadingIndicatorViewTest() = default;
@@ -26,6 +34,9 @@
     icon_ = std::make_unique<views::ImageView>();
     eche_icon_loading_indicatior_view_ =
         std::make_unique<EcheIconLoadingIndicatorView>(icon_.get());
+
+    const gfx::Rect initial_bounds(0, 0, kSizeInDip, kSizeInDip);
+    eche_icon_loading_indicatior_view_->SetBoundsRect(initial_bounds);
   }
 
   void TearDown() override {
@@ -70,4 +81,27 @@
   EXPECT_FALSE(eche_icon_loading_indicatior_view()->GetAnimating());
 }
 
+TEST_F(EcheIconLoadingIndicatorViewTest, OnPaintAnimating) {
+  gfx::Canvas canvas(gfx::Size(kSizeInDip, kSizeInDip), /*image_scale=*/1.0f,
+                     /*is_opaque=*/false);
+
+  eche_icon_loading_indicatior_view()->SetAnimating(true);
+  eche_icon_loading_indicatior_view()->OnPaint(&canvas);
+
+  // Expect the center of animation should be the same as controls layer color.
+  EXPECT_EQ(AshColorProvider::Get()->GetControlsLayerColor(
+                AshColorProvider::ControlsLayerType::kFocusRingColor),
+            canvas.GetBitmap().getColor(kSizeInDip / 2, kSizeInDip / 2));
+}
+
+TEST_F(EcheIconLoadingIndicatorViewTest, OnPaintNotAnimating) {
+  gfx::Canvas canvas(gfx::Size(kSizeInDip, kSizeInDip), /*image_scale=*/1.0f,
+                     /*is_opaque=*/false);
+
+  eche_icon_loading_indicatior_view()->OnPaint(&canvas);
+
+  // No paint if not animating.
+  EXPECT_EQ(0u, canvas.GetBitmap().getColor(kSizeInDip / 2, kSizeInDip / 2));
+}
+
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/webui/os_feedback_ui/os_feedback_ui.cc b/ash/webui/os_feedback_ui/os_feedback_ui.cc
index 13695c15..29d963c13 100644
--- a/ash/webui/os_feedback_ui/os_feedback_ui.cc
+++ b/ash/webui/os_feedback_ui/os_feedback_ui.cc
@@ -48,6 +48,7 @@
       {"descriptionRequired", IDS_FEEDBACK_TOOL_DESCRIPTION_REQUIRED},
       {"feedbackHelpLinkLabel", IDS_FEEDBACK_TOOL_FEEDBACK_HELP_LINK_LABEL},
       {"pageTitle", IDS_FEEDBACK_TOOL_PAGE_TITLE},
+      {"sendButtonLabel", IDS_FEEDBACK_TOOL_SEND_BUTTON_LABEL},
       // The help content strings are needed for browser tests.
       {"suggestedHelpContent", IDS_FEEDBACK_TOOL_SUGGESTED_HELP_CONTENT},
       {"popularHelpContent", IDS_FEEDBACK_TOOL_POPULAR_HELP_CONTENT},
diff --git a/ash/webui/os_feedback_ui/resources/share_data_page.html b/ash/webui/os_feedback_ui/resources/share_data_page.html
index 6a8a431..1a6e4267 100644
--- a/ash/webui/os_feedback_ui/resources/share_data_page.html
+++ b/ash/webui/os_feedback_ui/resources/share_data_page.html
@@ -143,7 +143,7 @@
     </cr-button>
     <cr-button id="buttonSend" class="action-button"
         on-click="handleSendButtonClicked_">
-      Send
+        [[i18n('sendButtonLabel')]]
     </cr-button>
   </div>
 </div>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html
index 79dee42..183f772 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.html
@@ -47,16 +47,6 @@
     min-width: 252px;
   }
 
-  #shelf {
-    background-color: var(--cros-separator-color);
-    border-top-left-radius: 16px;
-    border-top-right-radius: 16px;
-    bottom: 0;
-    height: 24px;
-    position: absolute;
-    width: 100%;
-  }
-
   ::slotted(personalization-theme) {
     grid-area: theme;
   }
@@ -94,7 +84,6 @@
         <div class="photo-images-border"></div>
         <img src$="[[getImageSrc_(image_)]]"
             alt$="[[getImageAltDescription_(image_)]]">
-        <div id="shelf"></div>
       </div>
     </template>
     <template is="dom-if" if="[[isPolicyControlled_(image_)]]">
@@ -103,7 +92,6 @@
         <img src$="[[getImageSrc_(image_)]]"
             aria-description="$i18n{managedSetting}"
             alt$="[[getImageAltDescription_(image_)]]">
-        <div id="shelf"></div>
       </div>
     </template>
   </template>
diff --git a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
index 3ce7f8a..4770fe7 100644
--- a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
+++ b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
@@ -374,13 +374,13 @@
     }
   }
 
-  getClassForEmptyTile_(tile: ImageTile): string {
+  private getClassForEmptyTile_(tile: ImageTile): string {
     return `photo-inner-container ${
         (this.isGooglePhotosTile_(tile) ? 'google-photos-empty' :
                                           'photo-empty')}`;
   }
 
-  getImageUrlForEmptyTile_(tile: ImageTile): string {
+  private getImageUrlForEmptyTile_(tile: ImageTile): string {
     return `chrome://personalization/common/${
         (this.isGooglePhotosTile_(tile) ? 'google_photos.svg' :
                                           'no_images.svg')}`;
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 5522b51..891a4cbd 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1878,6 +1878,7 @@
 
     deps += [
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
+      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sys",
       "//third_party/fuchsia-sdk/sdk/pkg/async-default",
@@ -3766,6 +3767,7 @@
       "fuchsia/service_directory_test_base.h",
       "fuchsia/service_provider_impl_unittest.cc",
       "fuchsia/system_build_info_unittest.cc",
+      "fuchsia/system_product_info_unittest.cc",
       "fuchsia/test_component_context_for_process_unittest.cc",
       "fuchsia/time_zone_data_unittest.cc",
       "message_loop/fd_watch_controller_posix_unittest.cc",
@@ -3777,6 +3779,7 @@
       ":test_log_listener_safe",
       ":testfidl",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
+      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem",
@@ -4004,7 +4007,6 @@
       "android/java/src/org/chromium/base/NativeLibraryLoadedStatus.java",
       "android/java/src/org/chromium/base/annotations/AccessedByNative.java",
       "android/java/src/org/chromium/base/annotations/CalledByNative.java",
-      "android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java",
       "android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
       "android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java",
       "android/java/src/org/chromium/base/annotations/JNINamespace.java",
@@ -4385,7 +4387,6 @@
   }
 
   robolectric_library("base_junit_test_support") {
-    testonly = true
     sources = [
       "//third_party/robolectric/custom_asynctask/java/src/org/chromium/base/task/test/ShadowAsyncTask.java",
       "//third_party/robolectric/custom_asynctask/java/src/org/chromium/base/task/test/ShadowAsyncTaskBridge.java",
diff --git a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
index 814b786..d8013e3253 100644
--- a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
+++ b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
@@ -724,11 +724,11 @@
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 SHIM_ALWAYS_EXPORT struct mallinfo mallinfo(void) __THROW {
-  base::SimplePartitionStatsDumper allocator_dumper;
+  partition_alloc::SimplePartitionStatsDumper allocator_dumper;
   Allocator()->DumpStats("malloc", true, &allocator_dumper);
   // TODO(bartekn): Dump OriginalAllocator() into "malloc" as well.
 
-  base::SimplePartitionStatsDumper aligned_allocator_dumper;
+  partition_alloc::SimplePartitionStatsDumper aligned_allocator_dumper;
   if (AlignedAllocator() != Allocator()) {
     AlignedAllocator()->DumpStats("posix_memalign", true,
                                   &aligned_allocator_dumper);
@@ -737,13 +737,13 @@
   // Dump stats for nonscannable and nonquarantinable allocators.
   auto& nonscannable_allocator =
       base::internal::NonScannableAllocator::Instance();
-  base::SimplePartitionStatsDumper nonscannable_allocator_dumper;
+  partition_alloc::SimplePartitionStatsDumper nonscannable_allocator_dumper;
   if (auto* nonscannable_root = nonscannable_allocator.root())
     nonscannable_root->DumpStats("malloc", true,
                                  &nonscannable_allocator_dumper);
   auto& nonquarantinable_allocator =
       base::internal::NonQuarantinableAllocator::Instance();
-  base::SimplePartitionStatsDumper nonquarantinable_allocator_dumper;
+  partition_alloc::SimplePartitionStatsDumper nonquarantinable_allocator_dumper;
   if (auto* nonquarantinable_root = nonquarantinable_allocator.root())
     nonquarantinable_root->DumpStats("malloc", true,
                                      &nonquarantinable_allocator_dumper);
diff --git a/base/allocator/partition_allocator/PartitionAlloc.md b/base/allocator/partition_allocator/PartitionAlloc.md
index 15253d5..9d563e7 100644
--- a/base/allocator/partition_allocator/PartitionAlloc.md
+++ b/base/allocator/partition_allocator/PartitionAlloc.md
@@ -21,6 +21,8 @@
 branches. The number of operations in the fast paths is minimal, leading to the
 possibility of inlining.
 
+![general architecture](./dot/layers.png)
+
 However, even the fast path isn't the fastest, because it requires taking
 a per-partition lock. Although we optimized the lock, there was still room for
 improvement; to this end, we introduced the thread cache.
diff --git a/base/allocator/partition_allocator/address_pool_manager_types.h b/base/allocator/partition_allocator/address_pool_manager_types.h
index 976e37c5..f61f134 100644
--- a/base/allocator/partition_allocator/address_pool_manager_types.h
+++ b/base/allocator/partition_allocator/address_pool_manager_types.h
@@ -11,12 +11,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::pool_handle;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_TYPES_H_
diff --git a/base/allocator/partition_allocator/dot/layers.dot b/base/allocator/partition_allocator/dot/layers.dot
new file mode 100644
index 0000000..27ea7c6c
--- /dev/null
+++ b/base/allocator/partition_allocator/dot/layers.dot
@@ -0,0 +1,23 @@
+digraph G {
+  graph[bgcolor=transparent]
+  node[shape=box,style="filled,rounded",color=deepskyblue]
+
+  subgraph cluster_tc {
+    label = "Thread Cache"
+    rankdir = LR
+    {rank=same;TLS1,TLS2,TLSn}
+    TLS1->TLS2[style=invisible,dir=none]
+    TLS2->TLSn[style=dotted,dir=none]
+  }
+
+  subgraph cluster_central {
+    label = "Central Allocator (per-partition lock)"
+    fast[label="slot span freelists (fast path)"]
+    slow[label="slot span management (slow path)"]
+    # Forces slow path node beneath fast path node.
+    fast->slow[style=invisible,dir=none]
+  }
+
+  # Forces thread-external subgraph beneath thread cache subgraph.
+  TLS2->fast[style=invisible,dir=none]
+}
diff --git a/base/allocator/partition_allocator/dot/layers.png b/base/allocator/partition_allocator/dot/layers.png
new file mode 100644
index 0000000..80c78e2
--- /dev/null
+++ b/base/allocator/partition_allocator/dot/layers.png
Binary files differ
diff --git a/base/allocator/partition_allocator/memory_reclaimer.h b/base/allocator/partition_allocator/memory_reclaimer.h
index 2f52c7f1..491a379 100644
--- a/base/allocator/partition_allocator/memory_reclaimer.h
+++ b/base/allocator/partition_allocator/memory_reclaimer.h
@@ -71,12 +71,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::MemoryReclaimer;
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_MEMORY_RECLAIMER_H_
diff --git a/base/allocator/partition_allocator/memory_reclaimer_unittest.cc b/base/allocator/partition_allocator/memory_reclaimer_unittest.cc
index 3c8193a..f9f1bb0 100644
--- a/base/allocator/partition_allocator/memory_reclaimer_unittest.cc
+++ b/base/allocator/partition_allocator/memory_reclaimer_unittest.cc
@@ -41,7 +41,7 @@
 
  protected:
   void SetUp() override {
-    base::PartitionAllocGlobalInit(HandleOOM);
+    PartitionAllocGlobalInit(HandleOOM);
     MemoryReclaimer::Instance()->ResetForTesting();
     allocator_ = std::make_unique<PartitionAllocator>();
     allocator_->init({
@@ -58,7 +58,7 @@
   void TearDown() override {
     allocator_ = nullptr;
     MemoryReclaimer::Instance()->ResetForTesting();
-    base::PartitionAllocGlobalUninitForTesting();
+    PartitionAllocGlobalUninitForTesting();
   }
 
   void Reclaim() { MemoryReclaimer::Instance()->ReclaimNormal(); }
diff --git a/base/allocator/partition_allocator/partition_alloc-inl.h b/base/allocator/partition_allocator/partition_alloc-inl.h
index f973695..be21026 100644
--- a/base/allocator/partition_allocator/partition_alloc-inl.h
+++ b/base/allocator/partition_allocator/partition_alloc-inl.h
@@ -63,15 +63,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::SecureMemset;
-#if !BUILDFLAG(PA_DCHECK_IS_ON)
-using ::partition_alloc::internal::RandomPeriod;
-#endif  // !BUILDFLAG(PA_DCHECK_IS_ON)
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_INL_H_
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h
index bb1ece3..a6006919 100644
--- a/base/allocator/partition_allocator/partition_alloc.h
+++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -43,14 +43,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::PartitionAllocator;
-using ::partition_alloc::PartitionAllocGlobalInit;
-using ::partition_alloc::PartitionAllocGlobalUninitForTesting;
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H_
diff --git a/base/allocator/partition_allocator/partition_alloc_hooks.h b/base/allocator/partition_allocator/partition_alloc_hooks.h
index 48b08d7..33539e5 100644
--- a/base/allocator/partition_allocator/partition_alloc_hooks.h
+++ b/base/allocator/partition_allocator/partition_alloc_hooks.h
@@ -82,12 +82,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::PartitionAllocHooks;
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_HOOKS_H_
diff --git a/base/allocator/partition_allocator/partition_bucket.h b/base/allocator/partition_allocator/partition_bucket.h
index d35ad9f..25a0628 100644
--- a/base/allocator/partition_allocator/partition_bucket.h
+++ b/base/allocator/partition_allocator/partition_bucket.h
@@ -202,12 +202,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::PartitionBucket;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_BUCKET_H_
diff --git a/base/allocator/partition_allocator/partition_bucket_lookup.h b/base/allocator/partition_allocator/partition_bucket_lookup.h
index 75fb57eb..92f9aab 100644
--- a/base/allocator/partition_allocator/partition_bucket_lookup.h
+++ b/base/allocator/partition_allocator/partition_bucket_lookup.h
@@ -270,12 +270,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::BucketIndexLookup;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_BUCKET_LOOKUP_H_
diff --git a/base/allocator/partition_allocator/partition_cookie.h b/base/allocator/partition_allocator/partition_cookie.h
index a3fe230..5c07a91 100644
--- a/base/allocator/partition_allocator/partition_cookie.h
+++ b/base/allocator/partition_allocator/partition_cookie.h
@@ -44,18 +44,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::kCookieSize;
-using ::partition_alloc::internal::kPartitionCookieSizeAdjustment;
-using ::partition_alloc::internal::PartitionCookieCheckValue;
-using ::partition_alloc::internal::PartitionCookieWriteValue;
-#if BUILDFLAG(PA_DCHECK_IS_ON)
-using ::partition_alloc::internal::kCookieValue;
-#endif  // BUILDFLAG(PA_DCHECK_IS_ON)
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_COOKIE_H_
diff --git a/base/allocator/partition_allocator/partition_direct_map_extent.h b/base/allocator/partition_allocator/partition_direct_map_extent.h
index e2160cca..2e5b1d5 100644
--- a/base/allocator/partition_allocator/partition_direct_map_extent.h
+++ b/base/allocator/partition_allocator/partition_direct_map_extent.h
@@ -72,13 +72,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::PartitionDirectMapExtent;
-using ::partition_alloc::internal::PartitionDirectMapMetadata;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_DIRECT_MAP_EXTENT_H_
diff --git a/base/allocator/partition_allocator/partition_freelist_entry.h b/base/allocator/partition_allocator/partition_freelist_entry.h
index ac097fb..57af17b9 100644
--- a/base/allocator/partition_allocator/partition_freelist_entry.h
+++ b/base/allocator/partition_allocator/partition_freelist_entry.h
@@ -327,12 +327,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::PartitionFreelistEntry;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_FREELIST_ENTRY_H_
diff --git a/base/allocator/partition_allocator/partition_stats.h b/base/allocator/partition_allocator/partition_stats.h
index cb51e53..62325e3e 100644
--- a/base/allocator/partition_allocator/partition_stats.h
+++ b/base/allocator/partition_allocator/partition_stats.h
@@ -129,16 +129,4 @@
 
 }  // namespace partition_alloc
 
-namespace base {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::PartitionBucketMemoryStats;
-using ::partition_alloc::PartitionMemoryStats;
-using ::partition_alloc::PartitionStatsDumper;
-using ::partition_alloc::SimplePartitionStatsDumper;
-using ::partition_alloc::ThreadCacheStats;
-
-}  // namespace base
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_STATS_H_
diff --git a/base/allocator/partition_allocator/reservation_offset_table.h b/base/allocator/partition_allocator/reservation_offset_table.h
index 18daf13..4722f58 100644
--- a/base/allocator/partition_allocator/reservation_offset_table.h
+++ b/base/allocator/partition_allocator/reservation_offset_table.h
@@ -254,21 +254,4 @@
 
 }  // namespace partition_alloc::internal
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::internal::GetDirectMapReservationStart;
-using ::partition_alloc::internal::GetReservationOffsetTable;
-using ::partition_alloc::internal::GetReservationOffsetTableEnd;
-using ::partition_alloc::internal::IsManagedByDirectMap;
-using ::partition_alloc::internal::IsManagedByNormalBuckets;
-using ::partition_alloc::internal::IsManagedByNormalBucketsOrDirectMap;
-using ::partition_alloc::internal::IsReservationStart;
-using ::partition_alloc::internal::kOffsetTagNormalBuckets;
-using ::partition_alloc::internal::kOffsetTagNotAllocated;
-using ::partition_alloc::internal::ReservationOffsetPointer;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_RESERVATION_OFFSET_TABLE_H_
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h
index 8d9354e..dfb87c24b 100644
--- a/base/allocator/partition_allocator/thread_cache.h
+++ b/base/allocator/partition_allocator/thread_cache.h
@@ -611,13 +611,4 @@
 
 }  // namespace partition_alloc
 
-namespace base::internal {
-
-// TODO(https://crbug.com/1288247): Remove these 'using' declarations once
-// the migration to the new namespaces gets done.
-using ::partition_alloc::ThreadCache;
-using ::partition_alloc::ThreadCacheRegistry;
-
-}  // namespace base::internal
-
 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_THREAD_CACHE_H_
diff --git a/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java b/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java
deleted file mode 100644
index 512f3ad..0000000
--- a/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Used by the JNI generator to create the necessary JNI bindings and expose this method to native
- * test-only code.
- *
- * Any method annotated by this will be kept around for tests only. If you wish to call your method
- * from non-test code, see {@link CalledByNative} instead.
- */
-@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
-@Retention(RetentionPolicy.CLASS)
-public @interface CalledByNativeForTesting {
-    /*
-     *  If present, tells which inner class the method belongs to.
-     */
-    public String value() default "";
-}
diff --git a/base/android/jni_generator/golden/testCalledByNatives.golden b/base/android/jni_generator/golden/testCalledByNatives.golden
index f647cc14..6249bd6 100644
--- a/base/android/jni_generator/golden/testCalledByNatives.golden
+++ b/base/android/jni_generator/golden/testCalledByNatives.golden
@@ -475,26 +475,4 @@
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
 
-static std::atomic<jmethodID> g_org_chromium_TestJni_returnIntArrayForTesting(nullptr);
-static base::android::ScopedJavaLocalRef<jintArray> Java_TestJni_returnIntArrayForTesting(JNIEnv*
-    env, const base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_TestJni_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_TestJni_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "returnIntArrayForTesting",
-          "()[I",
-          &g_org_chromium_TestJni_returnIntArrayForTesting);
-
-  jintArray ret =
-      static_cast<jintArray>(env->CallObjectMethod(obj.obj(),
-          call_context.base.method_id));
-  return base::android::ScopedJavaLocalRef<jintArray>(env, ret);
-}
-
 #endif  // org_chromium_TestJni_JNI
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index f119adf5..9032036 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -319,10 +319,6 @@
   return ''.join(out)
 
 
-def _NameIsTestOnly(name):
-  return name.endswith('ForTest') or name.endswith('ForTesting')
-
-
 class JniParams(object):
   """Get JNI related parameters."""
 
@@ -685,7 +681,7 @@
 
 # Regex to match a string like "@CalledByNative public void foo(int bar)".
 RE_CALLED_BY_NATIVE = re.compile(
-    r'@CalledByNative((?P<Unchecked>(?:Unchecked)?|ForTesting))(?:\("(?P<annotation>.*)"\))?'
+    r'@CalledByNative(?P<Unchecked>(?:Unchecked)?)(?:\("(?P<annotation>.*)"\))?'
     r'(?:\s+@\w+(?:\(.*\))?)*'  # Ignore any other annotations.
     r'\s+(?P<prefix>('
     r'(private|protected|public|static|abstract|final|default|synchronized)'
@@ -896,20 +892,8 @@
     if not isinstance(hash_b64, str):
       hash_b64 = hash_b64.decode()
 
-    long_hash = ('M' + hash_b64).rstrip('=')
-    hashed_name = long_hash[:ProxyHelpers.MAX_CHARS_FOR_HASHED_NATIVE_METHODS]
-
-    # If the method is a test-only method, we don't care about saving size on
-    # the method name, since it shouldn't show up in the binary. Additionally,
-    # if we just hash the name, our checkers which enforce that we have no
-    # "ForTesting" methods by checking for the suffix "ForTesting" will miss
-    # these. We could preserve the name entirely and not hash anything, but
-    # that risks collisions. So, instead, we just append "ForTesting" to any
-    # test-only hashes, to ensure we catch any test-only methods that
-    # shouldn't be in our final binary.
-    if _NameIsTestOnly(method_name):
-      return hashed_name + '_ForTesting'
-    return hashed_name
+    hashed_name = ('M' + hash_b64).rstrip('=')
+    return hashed_name[0:ProxyHelpers.MAX_CHARS_FOR_HASHED_NATIVE_METHODS]
 
   @staticmethod
   def CreateProxyMethodName(fully_qualified_class, old_name, use_hash=False):
@@ -927,18 +911,12 @@
     return EscapeClassName(fully_qualified_class + '/' + old_name)
 
   @staticmethod
-  def ExtractStaticProxyNatives(fully_qualified_class,
-                                contents,
-                                ptr_type,
-                                include_test_only=True):
+  def ExtractStaticProxyNatives(fully_qualified_class, contents, ptr_type):
     methods = []
     for match in _NATIVE_PROXY_EXTRACTION_REGEX.finditer(contents):
       interface_body = match.group('interface_body')
       for method in _EXTRACT_METHODS_REGEX.finditer(interface_body):
         name = method.group('name')
-        if not include_test_only and _NameIsTestOnly(name):
-          continue
-
         params = JniParams.Parse(method.group('params'), use_proxy_types=True)
         return_type = JavaTypeToProxyCast(method.group('return_type'))
         proxy_name = ProxyHelpers.CreateProxyMethodName(fully_qualified_class,
@@ -1636,9 +1614,6 @@
   parser.add_argument('--unchecked_exceptions',
                       action='store_true',
                       help='Do not check that no exceptions were thrown.')
-  parser.add_argument('--include_test_only',
-                      action='store_true',
-                      help='Whether to maintain ForTesting JNI methods.')
   parser.add_argument(
       '--use_proxy_hash',
       action='store_true',
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index beb766e50..1997061 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -64,7 +64,6 @@
     self.always_mangle = False
     self.unchecked_exceptions = False
     self.split_name = None
-    self.include_test_only = True
 
 
 class BaseTest(unittest.TestCase):
@@ -586,9 +585,6 @@
 
     @CalledByNative
     public List<Bitmap.CompressFormat> getCompressFormatList();
-
-    @CalledByNativeForTesting
-    public int[] returnIntArrayForTesting();
     """
     jni_params = jni_generator.JniParams('org/chromium/Foo')
     jni_params.ExtractImportsAndInnerClasses(test_data)
@@ -828,17 +824,6 @@
             env_call=('Void', ''),
             unchecked=False,
         ),
-        CalledByNative(
-            return_type='int[]',
-            system_class=False,
-            static=False,
-            name='returnIntArrayForTesting',
-            method_id_var_name='returnIntArrayForTesting',
-            java_class_name='',
-            params=[],
-            env_call=('Void', ''),
-            unchecked=False,
-        ),
     ]
     self.AssertListEquals(golden_called_by_natives, called_by_natives)
     h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', [],
@@ -1403,59 +1388,6 @@
 
     self.AssertListEquals(_RemoveHashedNames(natives), golden_natives)
 
-  def testForTestingKept(self):
-    test_data = """
-    class SampleProxyJni {
-      @NativeMethods
-      interface Natives {
-        void fooForTesting();
-        void fooForTest();
-      }
-    }
-    """
-    qualified_clazz = 'org/chromium/example/SampleProxyJni'
-
-    natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
-        qualified_clazz, test_data, 'long', True)
-
-    golden_natives = [
-        NativeMethod(
-            return_type='void',
-            static=True,
-            name='fooForTesting',
-            params=[],
-            java_class_name=None,
-            is_proxy=True,
-            proxy_name='org_chromium_example_SampleProxyJni_fooForTesting'),
-        NativeMethod(
-            return_type='void',
-            static=True,
-            name='fooForTest',
-            params=[],
-            java_class_name=None,
-            is_proxy=True,
-            proxy_name='org_chromium_example_SampleProxyJni_fooForTest'),
-    ]
-
-    self.AssertListEquals(_RemoveHashedNames(natives), golden_natives)
-
-  def testForTestingRemoved(self):
-    test_data = """
-    class SampleProxyJni {
-      @NativeMethods
-      interface Natives {
-        void fooForTesting();
-        void fooForTest();
-      }
-    }
-    """
-    qualified_clazz = 'org/chromium/example/SampleProxyJni'
-
-    natives = jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
-        qualified_clazz, test_data, 'long', False)
-
-    self.AssertListEquals(_RemoveHashedNames(natives), [])
-
   def testProxyNativesMainDex(self):
     test_data = """
     @MainDex
diff --git a/base/android/jni_generator/jni_registration_generator.py b/base/android/jni_generator/jni_registration_generator.py
index eeaf58e..3226da2 100755
--- a/base/android/jni_generator/jni_registration_generator.py
+++ b/base/android/jni_generator/jni_registration_generator.py
@@ -41,8 +41,7 @@
               srcjar_path,
               proxy_opts,
               header_path=None,
-              namespace='',
-              include_test_only=True):
+              namespace=''):
   """Generates files required to perform JNI registration.
 
   Generates a srcjar containing a single class, GEN_JNI, that contains all
@@ -67,8 +66,7 @@
             _DictForPath,
             use_proxy_hash=proxy_opts.use_hash,
             enable_jni_multiplexing=proxy_opts.enable_jni_multiplexing,
-            namespace=namespace,
-            include_test_only=include_test_only), java_file_paths):
+            namespace=namespace), java_file_paths):
       if d:
         results.append(d)
 
@@ -137,8 +135,7 @@
 def _DictForPath(path,
                  use_proxy_hash=False,
                  enable_jni_multiplexing=False,
-                 namespace='',
-                 include_test_only=True):
+                 namespace=''):
   with open(path) as f:
     contents = jni_generator.RemoveComments(f.read())
     if '@JniIgnoreNatives' in contents:
@@ -151,8 +148,7 @@
   natives += jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
       fully_qualified_class=fully_qualified_class,
       contents=contents,
-      ptr_type='long',
-      include_test_only=include_test_only)
+      ptr_type='long')
   if len(natives) == 0:
     return None
   # The namespace for the content is separate from the namespace for the
@@ -922,9 +918,6 @@
       '--manual_jni_registration',
       action='store_true',
       help='Manually do JNI registration - required for crazy linker')
-  arg_parser.add_argument('--include_test_only',
-                          action='store_true',
-                          help='Whether to maintain ForTesting JNI methods.')
   args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:]))
 
   if not args.enable_proxy_mocks and args.require_mocks:
@@ -955,8 +948,7 @@
             args.srcjar_path,
             proxy_opts=proxy_opts,
             header_path=args.header_path,
-            namespace=args.namespace,
-            include_test_only=args.include_test_only)
+            namespace=args.namespace)
 
   if args.depfile:
     build_utils.WriteDepfile(args.depfile, args.srcjar_path,
diff --git a/base/fuchsia/system_info.cc b/base/fuchsia/system_info.cc
index 1fe1812..774a058 100644
--- a/base/fuchsia/system_info.cc
+++ b/base/fuchsia/system_info.cc
@@ -5,44 +5,45 @@
 #include "base/fuchsia/system_info.h"
 
 #include <fuchsia/buildinfo/cpp/fidl.h>
+#include <fuchsia/hwinfo/cpp/fidl.h>
 #include <lib/sys/cpp/component_context.h>
 
 #include "base/check.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/process_context.h"
+#include "base/location.h"
+#include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/threading/scoped_blocking_call.h"
-#include "base/threading/thread_restrictions.h"
 
 namespace base {
 
 namespace {
 
-fuchsia::buildinfo::BuildInfo FetchSystemBuildInfo() {
-  ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);
-
-  fuchsia::buildinfo::ProviderSyncPtr build_info_provider_sync;
-  ComponentContextForProcess()->svc()->Connect(
-      build_info_provider_sync.NewRequest());
-
-  fuchsia::buildinfo::BuildInfo build_info;
-  zx_status_t status = build_info_provider_sync->GetBuildInfo(&build_info);
-  ZX_DCHECK(status == ZX_OK, status);
-  DCHECK(!build_info.IsEmpty()) << "FIDL service returned empty BuildInfo";
-  return build_info;
-}
-
-// Returns this process's BuildInfo object.
+// Returns this process's cached object for `BuildInfo`.
 fuchsia::buildinfo::BuildInfo& CachedBuildInfo() {
   static NoDestructor<fuchsia::buildinfo::BuildInfo> build_info;
   return *build_info;
 }
 
+// Synchronously fetches BuildInfo from the system and caches it for use in this
+// process.
+void FetchAndCacheBuildInfo() {
+  DCHECK(CachedBuildInfo().IsEmpty()) << "Only call once per process";
+
+  fuchsia::buildinfo::ProviderSyncPtr provider_sync;
+  ComponentContextForProcess()->svc()->Connect(provider_sync.NewRequest());
+
+  zx_status_t status = provider_sync->GetBuildInfo(&CachedBuildInfo());
+  ZX_CHECK(status == ZX_OK, status);
+  CHECK(!CachedBuildInfo().IsEmpty());
+}
+
 }  // namespace
 
 void FetchAndCacheSystemInfo() {
-  DCHECK(CachedBuildInfo().IsEmpty()) << "Only call once per process";
-  CachedBuildInfo() = FetchSystemBuildInfo();
+  ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);
+  FetchAndCacheBuildInfo();
 }
 
 const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo() {
@@ -51,6 +52,18 @@
   return CachedBuildInfo();
 }
 
+// Synchronously fetches ProductInfo from the system
+fuchsia::hwinfo::ProductInfo GetProductInfo() {
+  ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);
+  fuchsia::hwinfo::ProductSyncPtr provider_sync;
+  ComponentContextForProcess()->svc()->Connect(provider_sync.NewRequest());
+
+  fuchsia::hwinfo::ProductInfo product_info;
+  [[maybe_unused]] zx_status_t status = provider_sync->GetInfo(&product_info);
+  ZX_DLOG_IF(ERROR, status != ZX_OK, status);
+  return product_info;
+}
+
 void ClearCachedSystemInfoForTesting() {
   CachedBuildInfo() = {};
 }
diff --git a/base/fuchsia/system_info.h b/base/fuchsia/system_info.h
index 481e2ff..fe0382de 100644
--- a/base/fuchsia/system_info.h
+++ b/base/fuchsia/system_info.h
@@ -6,25 +6,31 @@
 #define BASE_FUCHSIA_SYSTEM_INFO_H_
 
 #include "base/base_export.h"
-#include "base/strings/string_piece_forward.h"
 
-namespace fuchsia {
-namespace buildinfo {
+namespace fuchsia::buildinfo {
 class BuildInfo;
 }
-}  // namespace fuchsia
+namespace fuchsia::hwinfo {
+class ProductInfo;
+}
 
 namespace base {
 
-// Fetches the build info from the system and caches it before returning.
-// Must be called in each process before calling other non-test functions.
+// Makes a blocking call to fetch the info from the system and caches it
+// before returning. Must be called in each process during the initialization
+// phase.
 BASE_EXPORT void FetchAndCacheSystemInfo();
 
 // Returns the cached build info.
 BASE_EXPORT const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo();
 
-// Reset the cached BuildInfo to empty so that FetchAndCacheSystemInfo()
-// can be called again in this process.
+// Synchronously fetches the system ProductInfo.
+// Returns empty ProductInfo if the required service is unavailable or returns
+// an error.
+BASE_EXPORT fuchsia::hwinfo::ProductInfo GetProductInfo();
+
+// Resets the cached system info to empty so that
+// FetchAndCacheSystemInfo() can be called again in this process.
 BASE_EXPORT void ClearCachedSystemInfoForTesting();
 
 }  // namespace base
diff --git a/base/fuchsia/system_product_info_unittest.cc b/base/fuchsia/system_product_info_unittest.cc
new file mode 100644
index 0000000..78af4f8
--- /dev/null
+++ b/base/fuchsia/system_product_info_unittest.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 "base/callback_forward.h"
+#include "base/fuchsia/system_info.h"
+
+#include <fuchsia/buildinfo/cpp/fidl.h>
+#include <fuchsia/hwinfo/cpp/fidl.h>
+#include <fuchsia/hwinfo/cpp/fidl_test_base.h>
+#include <memory>
+
+#include "base/bind.h"
+#include "base/fuchsia/scoped_service_binding.h"
+#include "base/fuchsia/scoped_service_publisher.h"
+#include "base/fuchsia/test_component_context_for_process.h"
+#include "base/location.h"
+#include "base/run_loop.h"
+#include "base/strings/string_piece_forward.h"
+#include "base/test/bind.h"
+#include "base/test/gtest_util.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "base/threading/sequence_bound.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+namespace {
+
+class FakeHardwareInfoProduct
+    : public fuchsia::hwinfo::testing::Product_TestBase {
+ public:
+  FakeHardwareInfoProduct(const base::StringPiece model,
+                          const base::StringPiece manufacturer,
+                          sys::OutgoingDirectory* outgoing_services)
+      : model_(model),
+        manufacturer_(manufacturer),
+        binding_(outgoing_services, this) {}
+  FakeHardwareInfoProduct(const FakeHardwareInfoProduct&) = delete;
+  FakeHardwareInfoProduct& operator=(const FakeHardwareInfoProduct&) = delete;
+  ~FakeHardwareInfoProduct() override = default;
+
+  // fuchsia::hwinfo::testing::Provider_TestBase implementation
+  void GetInfo(GetInfoCallback callback) override {
+    fuchsia::hwinfo::ProductInfo product_info;
+    product_info.set_model(model_);
+    product_info.set_manufacturer(manufacturer_);
+    callback(std::move(product_info));
+  }
+  void NotImplemented_(const std::string& name) final {
+    ADD_FAILURE() << "Unexpected call: " << name;
+  }
+
+ private:
+  std::string model_;
+  std::string manufacturer_;
+  ScopedServiceBinding<fuchsia::hwinfo::Product> binding_;
+};
+
+}  // namespace
+
+// Uses a fake "fuchsia.hwinfo.Product" implementation.
+// clears the cached ProductInfo to ensure that each test starts with no cached
+// ProductInfo and that subsequent tests runs do not use fake values.
+class ProductInfoTest : public testing::Test {
+ protected:
+  ProductInfoTest()
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::MainThreadType::IO),
+        thread_("ProductInfo Retrieval Thread") {
+    thread_.StartWithOptions(
+        base::Thread::Options(base::MessagePumpType::IO, 0));
+    ClearCachedSystemInfoForTesting();
+    component_context_.AddService(fuchsia::buildinfo::Provider::Name_);
+  }
+  ~ProductInfoTest() override { ClearCachedSystemInfoForTesting(); }
+
+  // Fetch the product info in a separate thread, while servicing the
+  // FIDL fake implementation on the main thread.
+  fuchsia::hwinfo::ProductInfo GetProductInfoViaTask() {
+    fuchsia::hwinfo::ProductInfo product_info;
+    base::RunLoop run_loop;
+    thread_.task_runner()->PostTaskAndReplyWithResult(
+        FROM_HERE, base::BindOnce(&GetProductInfo),
+        base::BindOnce(
+            [](base::RunLoop& run_loop,
+               fuchsia::hwinfo::ProductInfo& product_info,
+               fuchsia::hwinfo::ProductInfo result) {
+              product_info = std::move(result);
+              run_loop.Quit();
+            },
+            std::ref(run_loop), std::ref(product_info)));
+    run_loop.Run();
+    return product_info;
+  }
+
+  base::test::SingleThreadTaskEnvironment task_environment_;
+  TestComponentContextForProcess component_context_;
+  base::Thread thread_;
+};
+
+using ProductInfoDeathTest = ProductInfoTest;
+
+TEST_F(ProductInfoTest, GetProductInfoReturnsFakedValues) {
+  FakeHardwareInfoProduct hwinfo_product_provider(
+      "test.model", "test.manufacturer",
+      component_context_.additional_services());
+
+  const auto product_info = GetProductInfoViaTask();
+  EXPECT_EQ(product_info.model(), "test.model");
+  EXPECT_EQ(product_info.manufacturer(), "test.manufacturer");
+}
+
+TEST_F(ProductInfoTest, SystemServiceReturnsValidValues) {
+  component_context_.AddService(fuchsia::hwinfo::Product::Name_);
+
+  const auto product_info = GetProductInfoViaTask();
+  EXPECT_TRUE(product_info.has_model());
+  EXPECT_FALSE(product_info.model().empty());
+
+  EXPECT_TRUE(product_info.has_manufacturer());
+  EXPECT_FALSE(product_info.manufacturer().empty());
+}
+
+// TODO(crbug.com/101396): Re-enable once all clients
+// provide this service.
+TEST_F(ProductInfoDeathTest, DISABLED_DcheckOnServiceNotPresent) {
+  EXPECT_DCHECK_DEATH_WITH(GetProductInfoViaTask(), "ZX_ERR_PEER_CLOSED");
+}
+
+}  // namespace base
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index b632a47..c011e14 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -53,6 +53,8 @@
       return JSONParser::kUnsupportedEncoding;
     case JSONParser::JSON_UNQUOTED_DICTIONARY_KEY:
       return JSONParser::kUnquotedDictionaryKey;
+    case JSONParser::JSON_TOO_LARGE:
+      return JSONParser::kInputTooLarge;
     case JSONParser::JSON_UNREPRESENTABLE_NUMBER:
       return JSONParser::kUnrepresentableNumber;
     case JSONParser::JSON_PARSE_ERROR_COUNT:
@@ -107,6 +109,7 @@
     "Unsupported encoding. JSON must be UTF-8.";
 const char JSONParser::kUnquotedDictionaryKey[] =
     "Dictionary keys must be quoted.";
+const char JSONParser::kInputTooLarge[] = "Input string is too large (>2GB).";
 const char JSONParser::kUnrepresentableNumber[] =
     "Number cannot be represented.";
 
@@ -140,12 +143,19 @@
   // index of the imaginary '\n' immediately before the start of the string:
   // 'A' is in column (0 - -1) = 1.
   line_number_ = 1;
-  index_last_line_ = static_cast<size_t>(-1);
+  index_last_line_ = -1;
 
   error_code_ = JSON_NO_ERROR;
   error_line_ = 0;
   error_column_ = 0;
 
+  // ICU and ReadUnicodeCharacter() use int32_t for lengths, so ensure
+  // that the index_ will not overflow when parsing.
+  if (!base::IsValueInRangeForNumericType<int32_t>(input.length())) {
+    ReportError(JSON_TOO_LARGE, -1);
+    return absl::nullopt;
+  }
+
   // When the input JSON string starts with a UTF-8 Byte-Order-Mark,
   // advance the start position to avoid the ParseNextToken function mis-
   // treating a Unicode BOM as an invalid character and returning NULL.
@@ -205,7 +215,7 @@
     if (UNLIKELY(point == kUnicodeReplacementPoint)) {
       string_->append(kUnicodeReplacementString);
     } else {
-      WriteUnicodeCharacter(static_cast<base_icu::UChar32>(point), &*string_);
+      WriteUnicodeCharacter(point, &*string_);
     }
   }
 }
@@ -254,7 +264,7 @@
 }
 
 const char* JSONParser::pos() {
-  CHECK_LE(index_, input_.length());
+  CHECK_LE(static_cast<size_t>(index_), input_.length());
   return input_.data() + index_;
 }
 
@@ -531,7 +541,8 @@
 
   while (PeekChar()) {
     base_icu::UChar32 next_char = 0;
-    if (!ReadUnicodeCharacter(input_.data(), input_.length(), &index_,
+    if (!ReadUnicodeCharacter(input_.data(),
+                              static_cast<int32_t>(input_.length()), &index_,
                               &next_char) ||
         !IsValidCodepoint(next_char)) {
       if ((options_ & JSON_REPLACE_INVALID_CHARACTERS) == 0) {
@@ -736,8 +747,8 @@
 
 absl::optional<Value> JSONParser::ConsumeNumber() {
   const char* num_start = pos();
-  const size_t start_index = index_;
-  size_t end_index = start_index;
+  const int start_index = index_;
+  int end_index = start_index;
 
   if (PeekChar() == '-')
     ConsumeChar();
@@ -776,7 +787,7 @@
   // so save off where the parser should be on exit (see Consume invariant at
   // the top of the header), then make sure the next token is one which is
   // valid.
-  size_t exit_index = index_;
+  int exit_index = index_;
 
   switch (GetNextToken()) {
     case T_OBJECT_END:
diff --git a/base/json/json_parser.h b/base/json/json_parser.h
index aad1b3a..6cdd1e08 100644
--- a/base/json/json_parser.h
+++ b/base/json/json_parser.h
@@ -54,6 +54,7 @@
     JSON_UNEXPECTED_DATA_AFTER_ROOT,
     JSON_UNSUPPORTED_ENCODING,
     JSON_UNQUOTED_DICTIONARY_KEY,
+    JSON_TOO_LARGE,
     JSON_UNREPRESENTABLE_NUMBER,
     JSON_PARSE_ERROR_COUNT
   };
@@ -67,6 +68,7 @@
   static const char kUnexpectedDataAfterRoot[];
   static const char kUnsupportedEncoding[];
   static const char kUnquotedDictionaryKey[];
+  static const char kInputTooLarge[];
   static const char kUnrepresentableNumber[];
 
   explicit JSONParser(int options, size_t max_depth = kAbsoluteMaxDepth);
@@ -251,7 +253,7 @@
   StringPiece input_;
 
   // The index in the input stream to which the parser is wound.
-  size_t index_;
+  int index_;
 
   // The number of times the parser has recursed (current stack depth).
   size_t stack_depth_;
@@ -260,7 +262,7 @@
   int line_number_;
 
   // The last value of |index_| on the previous line.
-  size_t index_last_line_;
+  int index_last_line_;
 
   // Error information.
   JsonParseError error_code_;
diff --git a/base/json/string_escape.cc b/base/json/string_escape.cc
index 69362f7..4c1dbeb5 100644
--- a/base/json/string_escape.cc
+++ b/base/json/string_escape.cc
@@ -85,8 +85,12 @@
   if (put_in_quotes)
     dest->push_back('"');
 
-  const size_t length = str.length();
-  for (size_t i = 0; i < length; ++i) {
+  // Casting is necessary because ICU uses int32_t. Try and do so safely.
+  CHECK_LE(str.length(),
+           static_cast<size_t>(std::numeric_limits<int32_t>::max()));
+  const int32_t length = static_cast<int32_t>(str.length());
+
+  for (int32_t i = 0; i < length; ++i) {
     base_icu::UChar32 code_point;
     if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point) ||
         code_point == CBU_SENTINEL) {
diff --git a/base/memory/nonscannable_memory.cc b/base/memory/nonscannable_memory.cc
index 146b4534..6edfd74 100644
--- a/base/memory/nonscannable_memory.cc
+++ b/base/memory/nonscannable_memory.cc
@@ -53,7 +53,7 @@
 
 template <bool Quarantinable>
 void NonScannableAllocatorImpl<Quarantinable>::NotifyPCScanEnabled() {
-  allocator_.reset(MakePCScanMetadata<base::PartitionAllocator>());
+  allocator_.reset(MakePCScanMetadata<partition_alloc::PartitionAllocator>());
   allocator_->init({
       PartitionOptions::AlignedAlloc::kDisallowed,
       PartitionOptions::ThreadCache::kDisabled,
diff --git a/base/memory/nonscannable_memory.h b/base/memory/nonscannable_memory.h
index 961ab021..f607bdf6 100644
--- a/base/memory/nonscannable_memory.h
+++ b/base/memory/nonscannable_memory.h
@@ -59,7 +59,8 @@
   NonScannableAllocatorImpl();
   ~NonScannableAllocatorImpl();
 
-  std::unique_ptr<base::PartitionAllocator, PCScanMetadataDeleter> allocator_;
+  std::unique_ptr<partition_alloc::PartitionAllocator, PCScanMetadataDeleter>
+      allocator_;
   std::atomic_bool pcscan_enabled_{false};
 };
 
diff --git a/base/memory/raw_ptr.cc b/base/memory/raw_ptr.cc
index 9bfe23b..cf1052b 100644
--- a/base/memory/raw_ptr.cc
+++ b/base/memory/raw_ptr.cc
@@ -70,11 +70,12 @@
 
 #if DCHECK_IS_ON() || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS)
 void CheckThatAddressIsntWithinFirstPartitionPage(uintptr_t address) {
-  if (IsManagedByDirectMap(address)) {
-    uintptr_t reservation_start = GetDirectMapReservationStart(address);
+  if (partition_alloc::internal::IsManagedByDirectMap(address)) {
+    uintptr_t reservation_start =
+        partition_alloc::internal::GetDirectMapReservationStart(address);
     CHECK(address - reservation_start >= partition_alloc::PartitionPageSize());
   } else {
-    CHECK(IsManagedByNormalBuckets(address));
+    CHECK(partition_alloc::internal::IsManagedByNormalBuckets(address));
     CHECK(address % partition_alloc::kSuperPageSize >=
           partition_alloc::PartitionPageSize());
   }
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc
index de38ee6..2bd6c9e7 100644
--- a/base/memory/raw_ptr_unittest.cc
+++ b/base/memory/raw_ptr_unittest.cc
@@ -1060,8 +1060,8 @@
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
   base::CPU cpu;
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   int* raw_ptr1 =
       reinterpret_cast<int*>(allocator.root()->Alloc(sizeof(int), ""));
@@ -1103,8 +1103,8 @@
 TEST(BackupRefPtrImpl, ZeroSized) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
 
   std::vector<raw_ptr<void>> ptrs;
@@ -1118,8 +1118,8 @@
 
 TEST(BackupRefPtrImpl, EndPointer) {
   // This test requires a fresh partition with an empty free list.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
 
   // Check multiple size buckets and levels of slot filling.
@@ -1152,8 +1152,8 @@
 }
 
 TEST(BackupRefPtrImpl, QuarantinedBytes) {
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   uint64_t* raw_ptr1 = reinterpret_cast<uint64_t*>(
       allocator.root()->Alloc(sizeof(uint64_t), ""));
@@ -1192,8 +1192,8 @@
 TEST(BackupRefPtrImpl, ReinterpretCast) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
 
   void* ptr = allocator.root()->Alloc(16, "");
@@ -1231,8 +1231,8 @@
 TEST(BackupRefPtrImpl, RawPtrMayDangle) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   ScopedInstallDanglingRawPtrChecks enable_dangling_raw_ptr_checks;
 
@@ -1245,8 +1245,8 @@
 TEST(BackupRefPtrImpl, RawPtrNotDangling) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   ScopedInstallDanglingRawPtrChecks enable_dangling_raw_ptr_checks;
 
@@ -1269,8 +1269,8 @@
 TEST(BackupRefPtrImpl, DanglingPtrComparison) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   ScopedInstallDanglingRawPtrChecks enable_dangling_raw_ptr_checks;
 
@@ -1306,8 +1306,8 @@
 TEST(BackupRefPtrImpl, DanglingPtrAssignment) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   ScopedInstallDanglingRawPtrChecks enable_dangling_raw_ptr_checks;
 
@@ -1339,8 +1339,8 @@
 TEST(BackupRefPtrImpl, DanglingPtrCopyContructor) {
   // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to
   // new/delete once PartitionAlloc Everywhere is fully enabled.
-  PartitionAllocGlobalInit(HandleOOM);
-  PartitionAllocator allocator;
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kOpts);
   ScopedInstallDanglingRawPtrChecks enable_dangling_raw_ptr_checks;
 
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
index 3ef8a29..2f8d8933 100644
--- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc
+++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -344,8 +344,8 @@
 #endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
 
 #if BUILDFLAG(USE_PARTITION_ALLOC) && !BUILDFLAG(IS_NACL)
-  PartitionAllocHooks::SetObserverHooks(&PartitionAllocHook,
-                                        &PartitionFreeHook);
+  partition_alloc::PartitionAllocHooks::SetObserverHooks(&PartitionAllocHook,
+                                                         &PartitionFreeHook);
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC) && !BUILDFLAG(IS_NACL)
 }
 
@@ -355,7 +355,7 @@
       &g_allocator_dispatch);  // IN-TEST
 #endif
 #if BUILDFLAG(USE_PARTITION_ALLOC) && !BUILDFLAG(IS_NACL)
-  PartitionAllocHooks::SetObserverHooks(nullptr, nullptr);
+  partition_alloc::PartitionAllocHooks::SetObserverHooks(nullptr, nullptr);
 #endif
 }
 
diff --git a/base/strings/escape.cc b/base/strings/escape.cc
index 8c79bcd..e9b9afc 100644
--- a/base/strings/escape.cc
+++ b/base/strings/escape.cc
@@ -61,7 +61,7 @@
       escaped.push_back(IntToHex(c >> 4));
       escaped.push_back(IntToHex(c & 0xf));
     } else {
-      escaped.push_back(static_cast<char>(c));
+      escaped.push_back(c);
     }
   }
   return escaped;
@@ -198,8 +198,8 @@
   char most_sig_digit(escaped_text[index + 1]);
   char least_sig_digit(escaped_text[index + 2]);
   if (IsHexDigit(most_sig_digit) && IsHexDigit(least_sig_digit)) {
-    *value = static_cast<unsigned char>(HexDigitToInt(most_sig_digit) * 16 +
-                                        HexDigitToInt(least_sig_digit));
+    *value =
+        HexDigitToInt(most_sig_digit) * 16 + HexDigitToInt(least_sig_digit);
     return true;
   }
   return false;
@@ -236,7 +236,7 @@
     }
   }
 
-  size_t char_index = 0;
+  int32_t char_index = 0;
   // Check if the unicode "character" that was just unescaped is valid.
   if (!ReadUnicodeCharacter(reinterpret_cast<char*>(bytes), num_bytes,
                             &char_index, code_point_out)) {
@@ -253,11 +253,10 @@
 
 // This method takes a Unicode code point and returns true if it should be
 // unescaped, based on |rules|.
-bool ShouldUnescapeCodePoint(UnescapeRule::Type rules,
-                             base_icu::UChar32 code_point) {
+bool ShouldUnescapeCodePoint(UnescapeRule::Type rules, uint32_t code_point) {
   // If this is an ASCII character, use the lookup table.
-  if (code_point >= 0 && code_point < 0x80) {
-    return kUrlUnescape[static_cast<size_t>(code_point)] ||
+  if (code_point < 0x80) {
+    return kUrlUnescape[code_point] ||
            // Allow some additional unescaping when flags are set.
            (code_point == ' ' && (rules & UnescapeRule::SPACES)) ||
            // Allow any of the prohibited but non-control characters when doing
@@ -419,7 +418,7 @@
       // sequences.
       unsigned char non_utf8_byte;
       if (UnescapeUnsignedByteAtIndex(escaped_text, i, &non_utf8_byte)) {
-        result.push_back(static_cast<char>(non_utf8_byte));
+        result.push_back(non_utf8_byte);
         if (adjustments)
           adjustments->push_back(OffsetAdjuster::Adjustment(i, 3, 1));
         i += 3;
@@ -570,7 +569,7 @@
     // UnescapeUnsignedByteAtIndex does bounds checking, so this is always safe
     // to call.
     if (UnescapeUnsignedByteAtIndex(escaped_text, i, &byte)) {
-      unescaped_text[output_index++] = static_cast<char>(byte);
+      unescaped_text[output_index++] = byte;
       i += 3;
       continue;
     }
@@ -596,7 +595,7 @@
   unescaped_text->clear();
 
   std::set<unsigned char> illegal_encoded_bytes;
-  for (unsigned char c = '\x00'; c < '\x20'; ++c) {
+  for (char c = '\x00'; c < '\x20'; ++c) {
     illegal_encoded_bytes.insert(c);
   }
   if (fail_on_path_separators) {
@@ -633,7 +632,7 @@
 std::u16string UnescapeForHTML(StringPiece16 input) {
   static const struct {
     const char* ampersand_code;
-    const char16_t replacement;
+    const char replacement;
   } kEscapeToChars[] = {
       {"&lt;", '<'},   {"&gt;", '>'},   {"&amp;", '&'},
       {"&quot;", '"'}, {"&#39;", '\''},
@@ -649,15 +648,14 @@
        ++iter) {
     if (*iter == '&') {
       // Potential ampersand encode char.
-      size_t index = static_cast<size_t>(iter - text.begin());
+      size_t index = iter - text.begin();
       for (size_t i = 0; i < std::size(kEscapeToChars); i++) {
         if (ampersand_chars[i].empty()) {
           ampersand_chars[i] = ASCIIToUTF16(kEscapeToChars[i].ampersand_code);
         }
         if (text.find(ampersand_chars[i], index) == index) {
-          text.replace(
-              iter, iter + static_cast<ptrdiff_t>(ampersand_chars[i].length()),
-              1, kEscapeToChars[i].replacement);
+          text.replace(iter, iter + ampersand_chars[i].length(), 1,
+                       kEscapeToChars[i].replacement);
           break;
         }
       }
diff --git a/base/strings/escape.h b/base/strings/escape.h
index 9eb6258..151993c 100644
--- a/base/strings/escape.h
+++ b/base/strings/escape.h
@@ -74,39 +74,41 @@
   // functions.
   typedef uint32_t Type;
 
-  // Don't unescape anything at all.
-  static constexpr Type NONE = 0;
+  enum {
+    // Don't unescape anything at all.
+    NONE = 0,
 
-  // Don't unescape anything special, but all normal unescaping will happen.
-  // This is a placeholder and can't be combined with other flags (since it's
-  // just the absence of them). All other unescape rules imply "normal" in
-  // addition to their special meaning. Things like escaped letters, digits,
-  // and most symbols will get unescaped with this mode.
-  static constexpr Type NORMAL = 1 << 0;
+    // Don't unescape anything special, but all normal unescaping will happen.
+    // This is a placeholder and can't be combined with other flags (since it's
+    // just the absence of them). All other unescape rules imply "normal" in
+    // addition to their special meaning. Things like escaped letters, digits,
+    // and most symbols will get unescaped with this mode.
+    NORMAL = 1 << 0,
 
-  // Convert %20 to spaces. In some places where we're showing URLs, we may
-  // want this. In places where the URL may be copied and pasted out, then
-  // you wouldn't want this since it might not be interpreted in one piece
-  // by other applications.  Other UTF-8 spaces will not be unescaped.
-  static constexpr Type SPACES = 1 << 1;
+    // Convert %20 to spaces. In some places where we're showing URLs, we may
+    // want this. In places where the URL may be copied and pasted out, then
+    // you wouldn't want this since it might not be interpreted in one piece
+    // by other applications.  Other UTF-8 spaces will not be unescaped.
+    SPACES = 1 << 1,
 
-  // Unescapes '/' and '\\'. If these characters were unescaped, the resulting
-  // URL won't be the same as the source one. Moreover, they are dangerous to
-  // unescape in strings that will be used as file paths or names. This value
-  // should only be used when slashes don't have special meaning, like data
-  // URLs.
-  static constexpr Type PATH_SEPARATORS = 1 << 2;
+    // Unescapes '/' and '\\'. If these characters were unescaped, the resulting
+    // URL won't be the same as the source one. Moreover, they are dangerous to
+    // unescape in strings that will be used as file paths or names. This value
+    // should only be used when slashes don't have special meaning, like data
+    // URLs.
+    PATH_SEPARATORS = 1 << 2,
 
-  // Unescapes various characters that will change the meaning of URLs,
-  // including '%', '+', '&', '#'. Does not unescape path separators.
-  // If these characters were unescaped, the resulting URL won't be the same
-  // as the source one. This flag is used when generating final output like
-  // filenames for URLs where we won't be interpreting as a URL and want to do
-  // as much unescaping as possible.
-  static constexpr Type URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS = 1 << 3;
+    // Unescapes various characters that will change the meaning of URLs,
+    // including '%', '+', '&', '#'. Does not unescape path separators.
+    // If these characters were unescaped, the resulting URL won't be the same
+    // as the source one. This flag is used when generating final output like
+    // filenames for URLs where we won't be interpreting as a URL and want to do
+    // as much unescaping as possible.
+    URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS = 1 << 3,
 
-  // URL queries use "+" for space. This flag controls that replacement.
-  static constexpr Type REPLACE_PLUS_WITH_SPACE = 1 << 4;
+    // URL queries use "+" for space. This flag controls that replacement.
+    REPLACE_PLUS_WITH_SPACE = 1 << 4,
+  };
 };
 
 // Unescapes |escaped_text| and returns the result.
diff --git a/base/strings/pattern.cc b/base/strings/pattern.cc
index 9b01b2a3..613ddc28 100644
--- a/base/strings/pattern.cc
+++ b/base/strings/pattern.cc
@@ -124,7 +124,7 @@
   base_icu::UChar32 operator()(const char** p, const char* end) {
     base_icu::UChar32 c;
     int offset = 0;
-    CBU8_NEXT(reinterpret_cast<const uint8_t*>(*p), offset, end - *p, c);
+    CBU8_NEXT(*p, offset, end - *p, c);
     *p += offset;
     return c;
   }
diff --git a/base/strings/safe_sprintf.cc b/base/strings/safe_sprintf.cc
index dbb0e3a4..12621c8 100644
--- a/base/strings/safe_sprintf.cc
+++ b/base/strings/safe_sprintf.cc
@@ -223,13 +223,8 @@
   // if |pad| is ' '.
   //
   // Returns "false", if the |buffer_| overflowed at any time.
-  bool IToASCII(bool sign,
-                bool upcase,
-                int64_t i,
-                size_t base,
-                char pad,
-                size_t padding,
-                const char* prefix);
+  bool IToASCII(bool sign, bool upcase, int64_t i, int base,
+                char pad, size_t padding, const char* prefix);
 
  private:
   // Increments |count_| by |inc| unless this would cause |count_| to
@@ -280,13 +275,9 @@
   size_t count_;
 };
 
-bool Buffer::IToASCII(bool sign,
-                      bool upcase,
-                      int64_t i,
-                      size_t base,
-                      char pad,
-                      size_t padding,
-                      const char* prefix) {
+
+bool Buffer::IToASCII(bool sign, bool upcase, int64_t i, int base,
+                      char pad, size_t padding, const char* prefix) {
   // Sanity check for parameters. None of these should ever fail, but see
   // above for the rationale why we can't call CHECK().
   DEBUG_CHECK(base >= 2);
@@ -304,7 +295,7 @@
   //   if (sign && i < 0)
   //     prefix = "-";
   //   num = abs(i);
-  size_t minint = 0;
+  int minint = 0;
   uint64_t num;
   if (sign && i < 0) {
     prefix = "-";
@@ -344,7 +335,7 @@
     }
   } else
     prefix = nullptr;
-  const size_t prefix_length = static_cast<size_t>(reverse_prefix - prefix);
+  const size_t prefix_length = reverse_prefix - prefix;
 
   // Loop until we have converted the entire number. Output at least one
   // character (i.e. '0').
@@ -393,8 +384,7 @@
       }
     } else {
       started = true;
-      Out((upcase ? kUpCaseHexDigits
-                  : kDownCaseHexDigits)[num % base + minint]);
+      Out((upcase ? kUpCaseHexDigits : kDownCaseHexDigits)[num%base + minint]);
     }
 
     minint = 0;
@@ -467,14 +457,13 @@
         // character from a space ' ' to a zero '0'.
         pad = ch == '0' ? '0' : ' ';
         for (;;) {
-          const size_t digit = static_cast<size_t>(ch - '0');
           // The maximum allowed padding fills all the available address
           // space and leaves just enough space to insert the trailing NUL.
           const size_t max_padding = kSSizeMax - 1;
-          if (padding > max_padding / 10 ||
-              10 * padding > max_padding - digit) {
-            DEBUG_CHECK(padding <= max_padding / 10 &&
-                        10 * padding <= max_padding - digit);
+          if (padding > max_padding/10 ||
+              10*padding > max_padding - (ch - '0')) {
+            DEBUG_CHECK(padding <= max_padding/10 &&
+                        10*padding <= max_padding - (ch - '0'));
             // Integer overflow detected. Skip the rest of the width until
             // we find the format character, then do the normal error handling.
           padding_overflow:
@@ -486,7 +475,7 @@
             }
             goto fail_to_expand;
           }
-          padding = 10 * padding + digit;
+          padding = 10*padding + ch - '0';
           if (padding > max_padding) {
             // This doesn't happen for "sane" values of kSSizeMax. But once
             // kSSizeMax gets smaller than about 10, our earlier range checks
@@ -563,9 +552,9 @@
         } else {
           // Pointer values require an actual pointer or a string.
           if (arg.type == Arg::POINTER) {
-            i = reinterpret_cast<intptr_t>(arg.ptr);
+            i = reinterpret_cast<uintptr_t>(arg.ptr);
           } else if (arg.type == Arg::STRING) {
-            i = reinterpret_cast<intptr_t>(arg.str);
+            i = reinterpret_cast<uintptr_t>(arg.str);
           } else if (arg.type == Arg::INT &&
                      arg.integer.width == sizeof(NULL) &&
                      arg.integer.i == 0) {  // Allow C++'s version of NULL
diff --git a/base/strings/string_piece.cc b/base/strings/string_piece.cc
index 28aabe4..95170da 100644
--- a/base/strings/string_piece.cc
+++ b/base/strings/string_piece.cc
@@ -129,7 +129,7 @@
                                          s.begin(), s.end());
   if (found == self.end())
     return BasicStringPiece<CharT>::npos;
-  return static_cast<size_t>(found - self.begin());
+  return found - self.begin();
 }
 
 size_t find_first_of(StringPiece16 self, StringPiece16 s, size_t pos) {
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 26a3b36..3bbc6e9 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -174,8 +174,7 @@
   while (char_index >= 0) {
     int32_t prev = char_index;
     base_icu::UChar32 code_point = 0;
-    CBU8_NEXT(reinterpret_cast<const uint8_t*>(data), char_index,
-              truncation_length, code_point);
+    CBU8_NEXT(data, char_index, truncation_length, code_point);
     if (!IsValidCharacter(code_point)) {
       char_index = prev - 1;
     } else {
@@ -184,7 +183,7 @@
   }
 
   if (char_index >= 0 )
-    *output = input.substr(0, static_cast<size_t>(char_index));
+    *output = input.substr(0, char_index);
   else
     output->clear();
 }
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc
index aee227c6..bcace27 100644
--- a/base/strings/stringprintf.cc
+++ b/base/strings/stringprintf.cc
@@ -65,14 +65,14 @@
   int result = vsnprintfT(stack_buf, std::size(stack_buf), format, ap_copy);
   va_end(ap_copy);
 
-  if (result >= 0 && static_cast<size_t>(result) < std::size(stack_buf)) {
+  if (result >= 0 && result < static_cast<int>(std::size(stack_buf))) {
     // It fit.
-    dst->append(stack_buf, static_cast<size_t>(result));
+    dst->append(stack_buf, result);
     return;
   }
 
   // Repeatedly increase buffer size until it fits.
-  size_t mem_length = std::size(stack_buf);
+  int mem_length = std::size(stack_buf);
   while (true) {
     if (result < 0) {
 #if BUILDFLAG(IS_WIN)
@@ -88,7 +88,7 @@
 #endif
     } else {
       // We need exactly "result + 1" characters.
-      mem_length = static_cast<size_t>(result) + 1;
+      mem_length = result + 1;
     }
 
     if (mem_length > 32 * 1024 * 1024) {
@@ -107,9 +107,9 @@
     result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy);
     va_end(ap_copy);
 
-    if ((result >= 0) && (static_cast<size_t>(result) < mem_length)) {
+    if ((result >= 0) && (result < mem_length)) {
       // It fit.
-      dst->append(&mem_buf[0], static_cast<size_t>(result));
+      dst->append(&mem_buf[0], result);
       return;
     }
   }
diff --git a/base/strings/sys_string_conversions_win.cc b/base/strings/sys_string_conversions_win.cc
index 340b25d..356064f 100644
--- a/base/strings/sys_string_conversions_win.cc
+++ b/base/strings/sys_string_conversions_win.cc
@@ -42,7 +42,7 @@
     return std::wstring();
 
   std::wstring wide;
-  wide.resize(static_cast<size_t>(charcount));
+  wide.resize(charcount);
   MultiByteToWideChar(code_page, 0, mb.data(), mb_length, &wide[0], charcount);
 
   return wide;
@@ -61,7 +61,7 @@
     return std::string();
 
   std::string mb;
-  mb.resize(static_cast<size_t>(charcount));
+  mb.resize(charcount);
   WideCharToMultiByte(code_page, 0, wide.data(), wide_length,
                       &mb[0], charcount, NULL, NULL);
 
diff --git a/base/strings/utf_offset_string_conversions.cc b/base/strings/utf_offset_string_conversions.cc
index b4eb0e8f..f243e58 100644
--- a/base/strings/utf_offset_string_conversions.cc
+++ b/base/strings/utf_offset_string_conversions.cc
@@ -39,8 +39,7 @@
   DCHECK(offset);
   if (*offset == std::u16string::npos)
     return;
-  size_t original_lengths = 0;
-  size_t output_lengths = 0;
+  int adjustment = 0;
   for (const auto& i : adjustments) {
     if (*offset <= i.original_offset)
       break;
@@ -48,10 +47,9 @@
       *offset = std::u16string::npos;
       return;
     }
-    original_lengths += i.original_length;
-    output_lengths += i.output_length;
+    adjustment += static_cast<int>(i.original_length - i.output_length);
   }
-  *offset += output_lengths - original_lengths;
+  *offset -= adjustment;
 
   if (*offset > limit)
     *offset = std::u16string::npos;
@@ -72,20 +70,17 @@
                                     size_t* offset) {
   if (*offset == std::u16string::npos)
     return;
-  size_t original_lengths = 0;
-  size_t output_lengths = 0;
+  int adjustment = 0;
   for (const auto& i : adjustments) {
-    if (*offset + original_lengths - output_lengths <= i.original_offset)
+    if (*offset + adjustment <= i.original_offset)
       break;
-    original_lengths += i.original_length;
-    output_lengths += i.output_length;
-    if ((*offset + original_lengths - output_lengths) <
-        (i.original_offset + i.original_length)) {
+    adjustment += static_cast<int>(i.original_length - i.output_length);
+    if ((*offset + adjustment) < (i.original_offset + i.original_length)) {
       *offset = std::u16string::npos;
       return;
     }
   }
-  *offset += original_lengths - output_lengths;
+  *offset += adjustment;
 }
 
 // static
@@ -154,15 +149,15 @@
       //   <=
       //   adjusted_iter->original_offset + shift +
       //       adjusted_iter->original_length
+
       // Modify the current |adjusted_iter| to include whatever collapsing
       // happened in |first_iter|, then advance to the next |first_adjustments|
       // because we dealt with the current one.
-
+      const int collapse = static_cast<int>(first_iter->original_length) -
+          static_cast<int>(first_iter->output_length);
       // This function does not know how to deal with a string that expands and
       // then gets modified, only strings that collapse and then get modified.
-      DCHECK_GT(first_iter->original_length, first_iter->output_length);
-      const size_t collapse =
-          first_iter->original_length - first_iter->output_length;
+      DCHECK_GT(collapse, 0);
       adjusted_iter->original_length += collapse;
       currently_collapsing += collapse;
       ++first_iter;
@@ -193,12 +188,14 @@
                     OffsetAdjuster::Adjustments* adjustments) {
   if (adjustments)
     adjustments->clear();
+  // ICU requires 32-bit numbers.
   bool success = true;
-  for (size_t i = 0; i < src_len; i++) {
+  int32_t src_len32 = static_cast<int32_t>(src_len);
+  for (int32_t i = 0; i < src_len32; i++) {
     base_icu::UChar32 code_point;
     size_t original_i = i;
     size_t chars_written = 0;
-    if (ReadUnicodeCharacter(src, src_len, &i, &code_point)) {
+    if (ReadUnicodeCharacter(src, src_len32, &i, &code_point)) {
       chars_written = WriteUnicodeCharacter(code_point, output);
     } else {
       chars_written = WriteUnicodeCharacter(0xFFFD, output);
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index 4b900bd..c530637 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -12,12 +12,11 @@
 // ReadUnicodeCharacter --------------------------------------------------------
 
 bool ReadUnicodeCharacter(const char* src,
-                          size_t src_len,
-                          size_t* char_index,
+                          int32_t src_len,
+                          int32_t* char_index,
                           base_icu::UChar32* code_point_out) {
   base_icu::UChar32 code_point;
-  CBU8_NEXT(reinterpret_cast<const uint8_t*>(src), *char_index, src_len,
-            code_point);
+  CBU8_NEXT(src, *char_index, src_len, code_point);
   *code_point_out = code_point;
 
   // The ICU macro above moves to the next char, we want to point to the last
@@ -29,12 +28,13 @@
 }
 
 bool ReadUnicodeCharacter(const char16_t* src,
-                          size_t src_len,
-                          size_t* char_index,
+                          int32_t src_len,
+                          int32_t* char_index,
                           base_icu::UChar32* code_point) {
   if (CBU16_IS_SURROGATE(src[*char_index])) {
-    if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) || !src_len ||
-        *char_index >= src_len - 1 || !CBU16_IS_TRAIL(src[*char_index + 1])) {
+    if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) ||
+        *char_index + 1 >= src_len ||
+        !CBU16_IS_TRAIL(src[*char_index + 1])) {
       // Invalid surrogate pair.
       return false;
     }
@@ -53,8 +53,8 @@
 
 #if defined(WCHAR_T_IS_UTF32)
 bool ReadUnicodeCharacter(const wchar_t* src,
-                          size_t src_len,
-                          size_t* char_index,
+                          int32_t src_len,
+                          int32_t* char_index,
                           base_icu::UChar32* code_point) {
   // Conversion is easy since the source is 32-bit.
   *code_point = src[*char_index];
@@ -66,21 +66,20 @@
 
 // WriteUnicodeCharacter -------------------------------------------------------
 
-size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
-                             std::string* output) {
-  if (code_point >= 0 && code_point <= 0x7f) {
+size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output) {
+  if (code_point <= 0x7f) {
     // Fast path the common case of one byte.
     output->push_back(static_cast<char>(code_point));
     return 1;
   }
 
+
   // CBU8_APPEND_UNSAFE can append up to 4 bytes.
   size_t char_offset = output->length();
   size_t original_char_offset = char_offset;
   output->resize(char_offset + CBU8_MAX_LENGTH);
 
-  CBU8_APPEND_UNSAFE(reinterpret_cast<uint8_t*>(output->data()), char_offset,
-                     code_point);
+  CBU8_APPEND_UNSAFE(&(*output)[0], char_offset, code_point);
 
   // CBU8_APPEND_UNSAFE will advance our pointer past the inserted character, so
   // it will represent the new length of the string.
@@ -88,10 +87,9 @@
   return char_offset - original_char_offset;
 }
 
-size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
-                             std::u16string* output) {
+size_t WriteUnicodeCharacter(uint32_t code_point, std::u16string* output) {
   if (CBU16_LENGTH(code_point) == 1) {
-    // The code point is in the Basic Multilingual Plane (BMP).
+    // Thie code point is in the Basic Multilingual Plane (BMP).
     output->push_back(static_cast<char16_t>(code_point));
     return 1;
   }
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h
index 1f6bc0e..2ca9262 100644
--- a/base/strings/utf_string_conversion_utils.h
+++ b/base/strings/utf_string_conversion_utils.h
@@ -49,21 +49,21 @@
 //
 // Returns true on success. On false, |*code_point| will be invalid.
 BASE_EXPORT bool ReadUnicodeCharacter(const char* src,
-                                      size_t src_len,
-                                      size_t* char_index,
+                                      int32_t src_len,
+                                      int32_t* char_index,
                                       base_icu::UChar32* code_point_out);
 
 // Reads a UTF-16 character. The usage is the same as the 8-bit version above.
 BASE_EXPORT bool ReadUnicodeCharacter(const char16_t* src,
-                                      size_t src_len,
-                                      size_t* char_index,
+                                      int32_t src_len,
+                                      int32_t* char_index,
                                       base_icu::UChar32* code_point);
 
 #if defined(WCHAR_T_IS_UTF32)
 // Reads UTF-32 character. The usage is the same as the 8-bit version above.
 BASE_EXPORT bool ReadUnicodeCharacter(const wchar_t* src,
-                                      size_t src_len,
-                                      size_t* char_index,
+                                      int32_t src_len,
+                                      int32_t* char_index,
                                       base_icu::UChar32* code_point);
 #endif  // defined(WCHAR_T_IS_UTF32)
 
@@ -71,21 +71,20 @@
 
 // Appends a UTF-8 character to the given 8-bit string.  Returns the number of
 // bytes written.
-BASE_EXPORT size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
+BASE_EXPORT size_t WriteUnicodeCharacter(uint32_t code_point,
                                          std::string* output);
 
 // Appends the given code point as a UTF-16 character to the given 16-bit
 // string.  Returns the number of 16-bit values written.
-BASE_EXPORT size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
+BASE_EXPORT size_t WriteUnicodeCharacter(uint32_t code_point,
                                          std::u16string* output);
 
 #if defined(WCHAR_T_IS_UTF32)
 // Appends the given UTF-32 character to the given 32-bit string.  Returns the
 // number of 32-bit values written.
-inline size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
-                                    std::wstring* output) {
+inline size_t WriteUnicodeCharacter(uint32_t code_point, std::wstring* output) {
   // This is the easy case, just append the character.
-  output->push_back(static_cast<wchar_t>(code_point));
+  output->push_back(code_point);
   return 1;
 }
 #endif  // defined(WCHAR_T_IS_UTF32)
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc
index daedeb7..35af9cd 100644
--- a/base/system/sys_info.cc
+++ b/base/system/sys_info.cc
@@ -103,7 +103,7 @@
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback));
-#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::MayBlock()}, base::BindOnce(&GetHardwareInfoSync),
       std::move(callback));
diff --git a/base/system/sys_info_fuchsia.cc b/base/system/sys_info_fuchsia.cc
index fd77757..25396a8 100644
--- a/base/system/sys_info_fuchsia.cc
+++ b/base/system/sys_info_fuchsia.cc
@@ -5,6 +5,7 @@
 #include "base/system/sys_info.h"
 
 #include <fuchsia/buildinfo/cpp/fidl.h>
+#include <fuchsia/hwinfo/cpp/fidl.h>
 #include <sys/statvfs.h>
 #include <zircon/syscalls.h>
 
@@ -206,4 +207,14 @@
   return getpagesize();
 }
 
+SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
+  const auto product_info = GetProductInfo();
+
+  return {
+      .manufacturer =
+          product_info.has_manufacturer() ? product_info.manufacturer() : "",
+      .model = product_info.has_model() ? product_info.model() : "",
+  };
+}
+
 }  // namespace base
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc
index 1b0bcae..226ef8c2 100644
--- a/base/system/sys_info_unittest.cc
+++ b/base/system/sys_info_unittest.cc
@@ -233,7 +233,7 @@
   EXPECT_TRUE(IsStringUTF8(hardware_info->model));
   bool empty_result_expected =
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) || \
-    BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+    BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
       false;
 #else
       true;
diff --git a/base/task/thread_pool/worker_thread.cc b/base/task/thread_pool/worker_thread.cc
index 05c1a48..2a13b6d 100644
--- a/base/task/thread_pool/worker_thread.cc
+++ b/base/task/thread_pool/worker_thread.cc
@@ -118,7 +118,7 @@
 
   // Timed out.
   if (!was_signaled) {
-    ThreadCache::PurgeCurrentThread();
+    partition_alloc::ThreadCache::PurgeCurrentThread();
 
     // The thread woke up to purge before its standard reclaim time. Sleep for
     // what's remaining until then.
diff --git a/base/task/thread_pool/worker_thread_unittest.cc b/base/task/thread_pool/worker_thread_unittest.cc
index 463902f..067497b 100644
--- a/base/task/thread_pool/worker_thread_unittest.cc
+++ b/base/task/thread_pool/worker_thread_unittest.cc
@@ -889,7 +889,8 @@
  public:
   void WaitForWork(WaitableEvent* wake_up_event) override {
     // Fill several buckets before going to sleep.
-    for (size_t size = 8; size < ThreadCache::kDefaultSizeThreshold; size++) {
+    for (size_t size = 8;
+         size < partition_alloc::ThreadCache::kDefaultSizeThreshold; size++) {
       void* data = malloc(size);
       // A simple malloc() / free() pair can be discarded by the compiler (and
       // is), making the test fail. It is sufficient to make |FreeForTest()| a
@@ -898,9 +899,11 @@
       FreeForTest(data);
     }
 
-    size_t cached_memory_before = ThreadCache::Get()->CachedMemory();
+    size_t cached_memory_before =
+        partition_alloc::ThreadCache::Get()->CachedMemory();
     WorkerThreadDefaultDelegate::WaitForWork(wake_up_event);
-    size_t cached_memory_after = ThreadCache::Get()->CachedMemory();
+    size_t cached_memory_after =
+        partition_alloc::ThreadCache::Get()->CachedMemory();
 
     if (!first_wakeup_done_) {
       // First time we sleep is a short sleep, no cache purging.
diff --git a/base/third_party/icu/icu_utf.h b/base/third_party/icu/icu_utf.h
index 6fa41010..16792c4 100644
--- a/base/third_party/icu/icu_utf.h
+++ b/base/third_party/icu/icu_utf.h
@@ -278,27 +278,25 @@
  * @see U8_APPEND
  * @stable ICU 2.4
  */
-#define CBU8_APPEND_UNSAFE(s, i, c)                             \
-  CBUPRV_BLOCK_MACRO_BEGIN {                                    \
-    uint32_t __uc = (uint32_t)(c);                              \
-    if (__uc <= 0x7f) {                                         \
-      (s)[(i)++] = (uint8_t)__uc;                               \
-    } else {                                                    \
-      if (__uc <= 0x7ff) {                                      \
-        (s)[(i)++] = (uint8_t)((__uc >> 6) | 0xc0);             \
-      } else {                                                  \
-        if (__uc <= 0xffff) {                                   \
-          (s)[(i)++] = (uint8_t)((__uc >> 12) | 0xe0);          \
-        } else {                                                \
-          (s)[(i)++] = (uint8_t)((__uc >> 18) | 0xf0);          \
-          (s)[(i)++] = (uint8_t)(((__uc >> 12) & 0x3f) | 0x80); \
-        }                                                       \
-        (s)[(i)++] = (uint8_t)(((__uc >> 6) & 0x3f) | 0x80);    \
-      }                                                         \
-      (s)[(i)++] = (uint8_t)((__uc & 0x3f) | 0x80);             \
-    }                                                           \
-  }                                                             \
-  CBUPRV_BLOCK_MACRO_END
+#define CBU8_APPEND_UNSAFE(s, i, c) CBUPRV_BLOCK_MACRO_BEGIN { \
+    uint32_t __uc=(c); \
+    if(__uc<=0x7f) { \
+        (s)[(i)++]=(uint8_t)__uc; \
+    } else { \
+        if(__uc<=0x7ff) { \
+            (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \
+        } else { \
+            if(__uc<=0xffff) { \
+                (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \
+            } else { \
+                (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \
+                (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \
+            } \
+            (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \
+        } \
+        (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \
+    } \
+} CBUPRV_BLOCK_MACRO_END
 
 // source/common/unicode/utf16.h
 
@@ -316,7 +314,7 @@
  * @return TRUE or FALSE
  * @stable ICU 2.4
  */
-#define CBU16_IS_LEAD(c) (((uint32_t)(c)&0xfffffc00) == 0xd800)
+#define CBU16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
 
 /**
  * Is this code unit a trail surrogate (U+dc00..U+dfff)?
@@ -324,7 +322,7 @@
  * @return TRUE or FALSE
  * @stable ICU 2.4
  */
-#define CBU16_IS_TRAIL(c) (((uint32_t)(c)&0xfffffc00) == 0xdc00)
+#define CBU16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
 
 /**
  * Is this code unit a surrogate (U+d800..U+dfff)?
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc
index fe40c571..e14c7e0f 100644
--- a/base/trace_event/malloc_dump_provider.cc
+++ b/base/trace_event/malloc_dump_provider.cc
@@ -211,11 +211,12 @@
 #endif
 
 #if BUILDFLAG(USE_PARTITION_ALLOC)
-void ReportPartitionAllocThreadCacheStats(ProcessMemoryDump* pmd,
-                                          MemoryAllocatorDump* dump,
-                                          const ThreadCacheStats& stats,
-                                          const std::string& metrics_suffix,
-                                          bool detailed) {
+void ReportPartitionAllocThreadCacheStats(
+    ProcessMemoryDump* pmd,
+    MemoryAllocatorDump* dump,
+    const partition_alloc::ThreadCacheStats& stats,
+    const std::string& metrics_suffix,
+    bool detailed) {
   dump->AddScalar("alloc_count", MemoryAllocatorDump::kTypeScalar,
                   stats.alloc_count);
   dump->AddScalar("alloc_hits", MemoryAllocatorDump::kTypeScalar,
@@ -257,7 +258,7 @@
 
 #if defined(PA_THREAD_CACHE_ALLOC_STATS)
     if (detailed) {
-      base::internal::BucketIndexLookup lookup{};
+      partition_alloc::internal::BucketIndexLookup lookup{};
       std::string name = dump->absolute_name();
       for (size_t i = 0; i < partition_alloc::kNumBuckets; i++) {
         size_t bucket_size = lookup.bucket_sizes()[i];
@@ -425,7 +426,7 @@
 
 void MemoryDumpPartitionStatsDumper::PartitionDumpTotals(
     const char* partition_name,
-    const base::PartitionMemoryStats* memory_stats) {
+    const partition_alloc::PartitionMemoryStats* memory_stats) {
   total_mmapped_bytes_ += memory_stats->total_mmapped_bytes;
   total_resident_bytes_ += memory_stats->total_resident_bytes;
   total_active_bytes_ += memory_stats->total_active_bytes;
@@ -503,7 +504,7 @@
 
 void MemoryDumpPartitionStatsDumper::PartitionsDumpBucketStats(
     const char* partition_name,
-    const base::PartitionBucketMemoryStats* memory_stats) {
+    const partition_alloc::PartitionBucketMemoryStats* memory_stats) {
   DCHECK(memory_stats->is_valid);
   std::string dump_name = GetPartitionDumpName(root_name_, partition_name);
   if (memory_stats->is_direct_map) {
diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h
index a76b208..36ebe81 100644
--- a/base/trace_event/malloc_dump_provider.h
+++ b/base/trace_event/malloc_dump_provider.h
@@ -71,7 +71,7 @@
 // PartitionAllocMemoryDumpProvider. This implements an interface that will
 // be called with memory statistics for each bucket in the allocator.
 class BASE_EXPORT MemoryDumpPartitionStatsDumper final
-    : public base::PartitionStatsDumper {
+    : public partition_alloc::PartitionStatsDumper {
  public:
   MemoryDumpPartitionStatsDumper(const char* root_name,
                                  ProcessMemoryDump* memory_dump,
@@ -83,11 +83,12 @@
   static const char* kPartitionsDumpName;
 
   // PartitionStatsDumper implementation.
-  void PartitionDumpTotals(const char* partition_name,
-                           const base::PartitionMemoryStats*) override;
+  void PartitionDumpTotals(
+      const char* partition_name,
+      const partition_alloc::PartitionMemoryStats*) override;
   void PartitionsDumpBucketStats(
       const char* partition_name,
-      const base::PartitionBucketMemoryStats*) override;
+      const partition_alloc::PartitionBucketMemoryStats*) override;
 
   size_t total_mmapped_bytes() const { return total_mmapped_bytes_; }
   size_t total_resident_bytes() const { return total_resident_bytes_; }
diff --git a/base/types/token_type.h b/base/types/token_type.h
index 0626eac..d34cfcbc 100644
--- a/base/types/token_type.h
+++ b/base/types/token_type.h
@@ -7,6 +7,7 @@
 
 #include <type_traits>
 
+#include "base/check.h"
 #include "base/types/strong_alias.h"
 #include "base/unguessable_token.h"
 
@@ -23,7 +24,12 @@
 
  public:
   TokenType() : Super(UnguessableToken::Create()) {}
-  explicit TokenType(const UnguessableToken& token) : Super(token) {}
+  explicit TokenType(const UnguessableToken& token) : Super(token) {
+    // Disallow attempts to force a null UnguessableToken into a strongly-typed
+    // token. Allowing in-place nullability of UnguessableToken was a design
+    // mistake; do not propagate that mistake here as well.
+    CHECK(!token.is_empty());
+  }
   TokenType(const TokenType& token) : Super(token.value()) {}
   TokenType(TokenType&& token) noexcept : Super(token.value()) {}
   TokenType& operator=(const TokenType& token) = default;
diff --git a/base/types/token_type_unittest.cc b/base/types/token_type_unittest.cc
index aec69a6..e4c4fce 100644
--- a/base/types/token_type_unittest.cc
+++ b/base/types/token_type_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/types/token_type.h"
 
+#include "base/test/gtest_util.h"
 #include "base/unguessable_token.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -43,4 +44,8 @@
   EXPECT_EQ(token2.ToString(), token2.value().ToString());
 }
 
+TEST(TokenType, TokenFromNullUnguessableToken) {
+  EXPECT_CHECK_DEATH({ FooToken{UnguessableToken::Null()}; });
+}
+
 }  // namespace base
diff --git a/base/values.cc b/base/values.cc
index 09f92b0..9916ccde 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -8,7 +8,7 @@
 // build time. Try not to raise this limit unless absolutely necessary. See
 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
 #ifndef NACL_TC_REV
-#pragma clang max_tokens_here 460000
+#pragma clang max_tokens_here 470000
 #endif
 
 #include <algorithm>
diff --git a/build/android/gyp/generate_linker_version_script.py b/build/android/gyp/generate_linker_version_script.py
index 3b963a5..995fcd7 100755
--- a/build/android/gyp/generate_linker_version_script.py
+++ b/build/android/gyp/generate_linker_version_script.py
@@ -35,9 +35,6 @@
       '--export-java-symbols',
       action='store_true',
       help='Export Java_* JNI methods')
-  parser.add_argument('--export-fortesting-java-symbols',
-                      action='store_true',
-                      help='Export Java_*_ForTesting JNI methods')
   parser.add_argument(
       '--export-symbol-allowlist-file',
       action='append',
@@ -51,38 +48,13 @@
       help='Export JNI_OnLoad_* methods')
   options = parser.parse_args()
 
-  if options.export_fortesting_java_symbols:
-    assert options.export_java_symbols, ('Must export java symbols if exporting'
-                                         'fortesting java symbols.')
-
   # JNI_OnLoad is always exported.
   # CrashpadHandlerMain() is the entry point to the Crashpad handler, required
   # for libcrashpad_handler_trampoline.so.
   symbol_list = ['CrashpadHandlerMain', 'JNI_OnLoad']
 
   if options.export_java_symbols:
-    if options.export_fortesting_java_symbols:
-      symbol_list.append('Java_*')
-    else:
-      # The linker uses unix shell globbing patterns, not regex. So, we have to
-      # include everything that doesn't end in "ForTest(ing)" with this set of
-      # globs.
-      symbol_list.append('Java_*[!F]orTesting')
-      symbol_list.append('Java_*[!o]rTesting')
-      symbol_list.append('Java_*[!r]Testing')
-      symbol_list.append('Java_*[!T]esting')
-      symbol_list.append('Java_*[!e]sting')
-      symbol_list.append('Java_*[!s]ting')
-      symbol_list.append('Java_*[!t]ing')
-      symbol_list.append('Java_*[!i]ng')
-      symbol_list.append('Java_*[!n]g')
-      symbol_list.append('Java_*[!F]orTest')
-      symbol_list.append('Java_*[!o]rTest')
-      symbol_list.append('Java_*[!r]Test')
-      symbol_list.append('Java_*[!T]est')
-      symbol_list.append('Java_*[!e]st')
-      symbol_list.append('Java_*[!s]t')
-      symbol_list.append('Java_*[!gt]')
+    symbol_list.append('Java_*')
 
   if options.export_feature_registrations:
     symbol_list.append('JNI_OnLoad_*')
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 4aea6f5..4f98699c 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -1101,7 +1101,7 @@
             'raw_logs.txt', 'raw_logs',
             output_manager.Datatype.TEXT) as raw_logs_file:
           raw_logs_file.write(raw_logs)
-      logging.critical('RAW LOGS: %s', raw_logs_file.Link())
+        logging.critical('RAW LOGS: %s', raw_logs_file.Link())
 
       with out_manager.ArchivedTempfile(
           'test_results_presentation.html',
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 392733e..8fc6a82 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -306,7 +306,7 @@
     ]
   } else if (is_linux || is_chromeos || is_android || current_os == "aix") {
     configs += [ "//build/config/gcc:executable_config" ]
-    if (is_chromecast) {
+    if (is_castos || is_cast_android) {
       configs += [ "//build/config/chromecast:executable_config" ]
     }
   }
@@ -337,7 +337,7 @@
       "//build/config/ios:ios_dynamic_flags",
       "//build/config/ios:ios_shared_library_flags",
     ]
-  } else if (is_chromecast) {
+  } else if (is_castos || is_cast_android) {
     configs += [ "//build/config/chromecast:shared_library_config" ]
   } else if (is_linux || is_chromeos || current_os == "aix") {
     configs += [ "//build/config/gcc:shared_library_config" ]
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 0c19c020..1cf45d1 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -142,7 +142,7 @@
   # google_play_services_package contains the path where individual client
   # targets (e.g. google_play_services_base_java) are located.
   if (!defined(google_play_services_package)) {
-    if (is_chromecast && chromecast_branding != "public") {
+    if (is_cast_android && chromecast_branding != "public") {
       google_play_services_package = "//chromecast/internal/android/prebuilt/google-play-services-first-party"
     } else {
       google_play_services_package = "//third_party/android_deps"
diff --git a/build/config/android/linker_version_script.gni b/build/config/android/linker_version_script.gni
index bcdd8ef..96d8b665 100644
--- a/build/config/android/linker_version_script.gni
+++ b/build/config/android/linker_version_script.gni
@@ -16,7 +16,6 @@
 #
 template("generate_linker_version_script") {
   action_with_pydeps(target_name) {
-    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
     script = "//build/android/gyp/generate_linker_version_script.py"
     outputs = [ invoker.linker_script ]
     inputs = []
@@ -24,9 +23,6 @@
 
     if (defined(invoker.export_java_symbols) && invoker.export_java_symbols) {
       args += [ "--export-java-symbols" ]
-      if (defined(invoker.testonly) && invoker.testonly) {
-        args += [ "--export-fortesting-java-symbols" ]
-      }
     }
 
     if (defined(invoker.export_feature_registrations) &&
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 84dc49e1..b564825 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -369,14 +369,6 @@
           ]
         }
       }
-      if (defined(invoker.include_testonly)) {
-        _include_testonly = invoker.include_testonly
-      } else {
-        _include_testonly = defined(testonly) && testonly
-      }
-      if (_include_testonly) {
-        args += [ "--include_test_only" ]
-      }
 
       if (use_hashed_jni_names) {
         args += [ "--use_proxy_hash" ]
diff --git a/build/config/android/test/classpath_order/BUILD.gn b/build/config/android/test/classpath_order/BUILD.gn
index af48416..a1e47ded 100644
--- a/build/config/android/test/classpath_order/BUILD.gn
+++ b/build/config/android/test/classpath_order/BUILD.gn
@@ -93,7 +93,6 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
   sources =
       [ "java/src/org/chromium/build/classpath_order/ClassPathOrderTest.java" ]
   deps = [
@@ -102,7 +101,6 @@
     ":z1_master_java",
     ":z2_dependency_java",
     "//testing/android/junit:junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/build/config/buildflags_paint_preview.gni b/build/config/buildflags_paint_preview.gni
index 57d8656a..b32e35c6 100644
--- a/build/config/buildflags_paint_preview.gni
+++ b/build/config/buildflags_paint_preview.gni
@@ -7,10 +7,10 @@
 
 declare_args() {
   # Enable basic paint preview support. Does not work on iOS. Should
-  # not be included with Chromecast.
+  # not be included with Chromecast hardware devices.
   # Used by //components/paint_preview and //third_party/harfbuzz-ng.
   # TODO(crbug.com/webrtc/11223) Move back this file in
   # //components/paint_preview/ once WebRTC doesn't roll harfbuzz-ng anymore,
   # for consistency sake.
-  enable_paint_preview = !is_chromecast && !is_ios
+  enable_paint_preview = !is_castos && !is_cast_android && !is_ios
 }
diff --git a/build/config/c++/BUILD.gn b/build/config/c++/BUILD.gn
index 2e5843b..62ee498 100644
--- a/build/config/c++/BUILD.gn
+++ b/build/config/c++/BUILD.gn
@@ -64,11 +64,7 @@
   # The Windows component build fails to link with libc++'s debug mode. See
   # https://crbug.com/923166#c33, https://crbug.com/923166#c44, and
   # https://llvm.org/PR41018.
-  #
-  # TODO(https://crbug.com/1327706): Figure out why thinlto builds fail to link
-  # with libc++'s debug mode after https://reviews.llvm.org/D103964, and then
-  # remove the !use_thin_lto`)
-  if (!(is_win && is_component_build) && !use_thin_lto) {
+  if (!(is_win && is_component_build)) {
     # libc++ has two levels of debug mode. Setting _LIBCPP_DEBUG to zero
     # enables most assertions. Setting it to one additionally enables iterator
     # debugging. See https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 289b5c5b..cff2d2e 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -2214,9 +2214,9 @@
   } else if (clang_use_default_sample_profile) {
     assert(build_with_chromium,
            "Our default profiles currently only apply to Chromium")
-    assert(is_android || is_chromeos || is_chromecast,
+    assert(is_android || is_chromeos || is_castos,
            "The current platform has no default profile")
-    if (is_android || is_chromecast) {
+    if (is_android || is_castos) {
       _clang_sample_profile = "//chrome/android/profiles/afdo.prof"
     } else {
       assert(chromeos_afdo_platform == "atom" ||
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 36108aaf7..4070cf74 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -130,11 +130,9 @@
   # https://chromium.googlesource.com/chromium/src/+/main/docs/design/sandbox.md#cet-shadow-stack
   enable_cet_shadow_stack = target_cpu == "x64"
 
-  # If true, optimize for size. Does not affect windows builds.
-  # Linux & Mac favor speed over size.
-  # TODO(brettw) it's weird that Mac and desktop Linux are different. We should
-  # explore favoring size over speed in this case as well.
-  optimize_for_size = is_android || is_chromecast || is_fuchsia || is_ios
+  # If true, optimize for size.
+  # Default to favoring speed over size for platforms not listed below.
+  optimize_for_size = is_android || is_ios || is_fuchsia || is_castos
 }
 
 assert(!is_cfi || use_thin_lto, "CFI requires ThinLTO")
@@ -218,7 +216,7 @@
 
 declare_args() {
   # Whether to use the gold linker from binutils instead of lld or bfd.
-  use_gold = !use_lld && !(is_chromecast && is_linux &&
+  use_gold = !use_lld && !(is_castos &&
                            (current_cpu == "arm" || current_cpu == "mipsel")) &&
              (((is_linux || is_chromeos_lacros) &&
                (current_cpu == "x64" || current_cpu == "x86" ||
@@ -285,7 +283,7 @@
     symbol_level = 1
   } else if ((!is_nacl && !is_linux && !is_chromeos && !is_fuchsia &&
               current_os != "aix") || is_debug || is_official_build ||
-             is_chromecast) {
+             is_castos || is_cast_android) {
     # Linux builds slower by having symbols as part of the target binary,
     # whereas Mac and Windows have them separate, so in Release Linux, default
     # them off, but keep them on for Official builds and Chromecast builds.
diff --git a/build/config/compiler/pgo/pgo.gni b/build/config/compiler/pgo/pgo.gni
index a5bb86b..c434b6eb 100644
--- a/build/config/compiler/pgo/pgo.gni
+++ b/build/config/compiler/pgo/pgo.gni
@@ -20,8 +20,11 @@
   if (!dcheck_always_on && is_official_build &&
       # TODO(crbug.com/1052397): Remove chromeos_is_browser_only once
       # target_os switch for lacros-chrome is completed.
+      # TODO(crbug.com/1336055): Update this now-outdated condition with regard
+      # to chromecast and determine whether chromeos_is_browser_only is
+      # obsolete.
       (is_win || is_mac ||
-       (is_linux && !chromeos_is_browser_only && !is_chromecast))) {
+       (is_linux && !is_castos && !chromeos_is_browser_only))) {
     chrome_pgo_phase = 2
   }
 
diff --git a/build/config/features.gni b/build/config/features.gni
index b34f2bb82..0464f06 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -23,14 +23,19 @@
   #
   # Note: this flag is used by WebRTC which is DEPSed into Chrome. Moving it
   # out of //build will require using the build_overrides directory.
-  proprietary_codecs = is_chrome_branded || is_chromecast
+  #
+  # Do not add any other conditions to the following line.
+  #
+  # TODO(crbug.com/1314528): Remove chromecast-related conditions and force
+  # builds to explicitly specify this.
+  proprietary_codecs = is_chrome_branded || is_castos || is_cast_android
 
   # libudev usage. This currently only affects the content layer.
-  use_udev = (is_linux || is_chromeos) && !is_chromecast
+  use_udev = (is_linux && !is_castos) || is_chromeos
 
   use_dbus = is_linux || is_chromeos
 
-  use_gio = is_linux && !is_chromecast
+  use_gio = is_linux && !is_castos
 }
 #
 # =============================================
diff --git a/build/config/fuchsia/BUILD.gn b/build/config/fuchsia/BUILD.gn
index d97dea3..b53737b 100644
--- a/build/config/fuchsia/BUILD.gn
+++ b/build/config/fuchsia/BUILD.gn
@@ -16,14 +16,11 @@
   # https://fuchsia.googlesource.com/zircon/+/master/system/private/zircon/stack.h#9),
   # but on other platforms it's much higher, so a variety of code assumes more
   # will be available. Raise to 8M which matches e.g. macOS.
-  ldflags = [ "-Wl,-z,stack-size=0x800000" ]
-
-  # Allow this in chromium-only builds, but do not allow this in Chromecast
-  # builds.
-  if (!is_chromecast) {
-    cflags_cc = [ "-fexperimental-relative-c++-abi-vtables" ]
-    ldflags += [ "-fexperimental-relative-c++-abi-vtables" ]
-  }
+  ldflags = [
+    "-Wl,-z,stack-size=0x800000",
+    "-fexperimental-relative-c++-abi-vtables",
+  ]
+  cflags_cc = [ "-fexperimental-relative-c++-abi-vtables" ]
 }
 
 # Files required to run on Fuchsia on isolated swarming clients.
diff --git a/build/config/fuchsia/test/minimum.shard.test-cml b/build/config/fuchsia/test/minimum.shard.test-cml
index 31ffcaf..e0887367 100644
--- a/build/config/fuchsia/test/minimum.shard.test-cml
+++ b/build/config/fuchsia/test/minimum.shard.test-cml
@@ -27,12 +27,6 @@
   ],
   use: [
     {
-      // Required by the build-info-service child.
-      directory: "build-info",
-      rights: [ "r*" ],
-      path: "/config/build-info",
-    },
-    {
       directory: "config-data",
       rights: [ "r*" ],
       path: "/config/data",
@@ -64,6 +58,7 @@
     },
     {
       protocol: [
+        "fuchsia.hwinfo.Product",
         "fuchsia.media.ProfileProvider",
         "fuchsia.process.Launcher",
         "fuchsia.sys.Loader",
diff --git a/build/config/fuchsia/test/minimum_capabilities.test-cmx b/build/config/fuchsia/test/minimum_capabilities.test-cmx
index 09c26346..ed903be 100644
--- a/build/config/fuchsia/test/minimum_capabilities.test-cmx
+++ b/build/config/fuchsia/test/minimum_capabilities.test-cmx
@@ -3,6 +3,11 @@
     "fuchsia.test": {
       "injected-services": {
         "fuchsia.buildinfo.Provider": "fuchsia-pkg://fuchsia.com/build-info-service#meta/build-info.cmx",
+        "fuchsia.factory.MiscFactoryStoreProvider": [
+            "fuchsia-pkg://fuchsia.com/fake_factory_store_providers#meta/misc.cmx",
+            "--config=/config/data/fuchsia.factory.MiscFactoryStoreProvider.config"
+        ],
+        "fuchsia.hwinfo.Product": "fuchsia-pkg://fuchsia.com/hwinfo#meta/hwinfo.cmx",
         "fuchsia.intl.PropertyProvider": "fuchsia-pkg://fuchsia.com/intl_property_manager#meta/intl_property_manager_v1.cmx"
       },
       "system-services": [
@@ -19,6 +24,8 @@
     ],
     "services": [
       "fuchsia.buildinfo.Provider",
+      "fuchsia.factory.MiscFactoryStoreProvider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
       "fuchsia.media.ProfileProvider",
diff --git a/build/config/gcc/BUILD.gn b/build/config/gcc/BUILD.gn
index 893dae1..0222d54 100644
--- a/build/config/gcc/BUILD.gn
+++ b/build/config/gcc/BUILD.gn
@@ -63,8 +63,9 @@
 #    configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
 #  }
 config("rpath_for_built_shared_libraries") {
-  if (!is_android && !is_chromecast && current_os != "aix") {
-    # Note: Android, Aix don't support rpath.
+  if (!is_android && current_os != "aix" && !is_castos) {
+    # Note: Android, Aix don't support rpath. Chromecast has its own logic for
+    # setting the rpath in //build/config/chromecast.
     if (current_toolchain != default_toolchain || gcc_target_rpath == "") {
       ldflags = [
         # Want to pass "\$". GN will re-escape as required for ninja.
diff --git a/build/config/linux/gtk/gtk.gni b/build/config/linux/gtk/gtk.gni
index 64e62f2..2362caa 100644
--- a/build/config/linux/gtk/gtk.gni
+++ b/build/config/linux/gtk/gtk.gni
@@ -6,7 +6,7 @@
 
 declare_args() {
   # Whether or not we should use libgtk.
-  use_gtk = is_linux && !is_chromecast
+  use_gtk = is_linux && !is_castos
 
   # The (major) version of GTK to build against.  A different version may be
   # loaded at runtime.
diff --git a/build/config/linux/libdrm/BUILD.gn b/build/config/linux/libdrm/BUILD.gn
index e9b40184..bf53fdb2 100644
--- a/build/config/linux/libdrm/BUILD.gn
+++ b/build/config/linux/libdrm/BUILD.gn
@@ -11,7 +11,7 @@
   # Controls whether the build should use the version of libdrm library shipped
   # with the system. In release builds of desktop Linux and Chrome OS we use the
   # system version. Some Chromecast devices use this as well.
-  use_system_libdrm = is_chromeos_device || (is_linux && !is_chromecast)
+  use_system_libdrm = is_chromeos_device || (is_linux && !is_castos)
 }
 
 if (use_system_libdrm) {
diff --git a/build/config/linux/pangocairo/pangocairo.gni b/build/config/linux/pangocairo/pangocairo.gni
index 6bc7529..1a81183 100644
--- a/build/config/linux/pangocairo/pangocairo.gni
+++ b/build/config/linux/pangocairo/pangocairo.gni
@@ -6,5 +6,5 @@
 import("//build/config/ui.gni")
 
 declare_args() {
-  use_pangocairo = is_linux && !is_chromecast
+  use_pangocairo = is_linux && !is_castos
 }
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index 8f13b01f..c3c58e2 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -463,7 +463,7 @@
 
     # Chromecast ubsan builds fail to compile with these
     # experimental flags, so only add them to non-chromecast ubsan builds.
-    if (!is_chromecast) {
+    if (!is_castos && !is_cast_android) {
       cflags += [
         # Employ the experimental PBQP register allocator to avoid slow
         # compilation on files with too many basic blocks.
diff --git a/build/config/ui.gni b/build/config/ui.gni
index 83ec3d7..247c80e7 100644
--- a/build/config/ui.gni
+++ b/build/config/ui.gni
@@ -33,16 +33,15 @@
   toolkit_views = is_mac || is_win || is_linux || is_chromeos || is_fuchsia
 
   use_glib =
-      is_linux && !is_chromecast &&
+      is_linux && !is_castos &&
       # Avoid the need for glib when Android is building things via secondary
       # toolchains.
       target_os != "android"
 }
 
-assert(!use_glib || (is_linux && !is_chromecast))
+assert(!use_glib || (is_linux && !is_castos))
 
-use_atk = is_linux && !is_chromecast && use_glib &&
-          current_toolchain == default_toolchain
+use_atk = use_glib && current_toolchain == default_toolchain
 
 # Whether using Xvfb to provide a display server for a test might be
 # necessary.
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 53b56db..c3fedbf 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220614.3.1
+8.20220616.0.1
diff --git a/build/linux/BUILD.gn b/build/linux/BUILD.gn
index cd49e3d..d50947fd 100644
--- a/build/linux/BUILD.gn
+++ b/build/linux/BUILD.gn
@@ -17,7 +17,7 @@
 # Looking for libspeechd? Use //third_party/speech-dispatcher
 
 if (use_system_freetype) {
-  assert(!is_chromecast)
+  assert(!is_castos)
 
   # Only provided for distributions which prefer to keep linking to FreeType on
   # the system, use with caution,for details see build/config/freetype/BUILD.gn.
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni
index 86d9ff7..1b97c8f 100644
--- a/build/toolchain/toolchain.gni
+++ b/build/toolchain/toolchain.gni
@@ -22,9 +22,9 @@
 }
 
 if (generate_linker_map) {
-  assert(is_official_build || is_chromecast,
+  assert(is_official_build || is_castos || is_cast_android,
          "Linker map files should only be generated when is_official_build = " +
-             "true or is_chromecast = true")
+             "true or is_castos = true or is_cast_android = true")
   assert(current_os == "android" || current_os == "linux" ||
              target_os == "android" || target_os == "linux" ||
              target_os == "chromeos",
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index c894060..ceb5b93 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "b1269813eaf5b8ac78e35e45a0f7cc320bd3e7d6"
+  libcxx_revision = "1a637088a36d19d4ba0358c5e2994c3c9e024a62"
 }
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
index b3e5378..14587f2 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -88,6 +88,7 @@
     "trunk/src/ios.cpp",
     "trunk/src/ios.instantiations.cpp",
     "trunk/src/iostream.cpp",
+    "trunk/src/legacy_debug_handler.cpp",
     "trunk/src/legacy_pointer_safety.cpp",
     "trunk/src/locale.cpp",
     "trunk/src/memory.cpp",
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 39e68be..c5226d6 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -1249,6 +1249,10 @@
   // will be deleted.
   if (layer_tree_impl()->IsSyncTree() && layer_tree_impl()->IsReadyToActivate())
     return false;
+  // To reduce memory usage, don't recreate highres tiling during scroll
+  if (ScrollInteractionInProgress())
+    return false;
+
   return true;
 }
 
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index e5b26bd8..053b3fef 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -2922,5 +2922,125 @@
 
 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestViewportAbortedCommit);
 
+class PreventRecreatingTilingDuringScroll : public LayerTreeHostScrollTest {
+ public:
+  PreventRecreatingTilingDuringScroll()
+      : initial_scale_(2.0f, 1.0f), new_scale_(2.0f, 2.0f) {}
+
+  void SetupTree() override {
+    LayerTreeHostScrollTest::SetupTree();
+
+    Layer* root_layer = layer_tree_host()->root_layer();
+    Layer* root_scroll_layer =
+        layer_tree_host()->OuterViewportScrollLayerForTesting();
+
+    child_layer_ = FakePictureLayer::Create(&client_);
+    child_layer_->SetElementId(
+        LayerIdToElementIdForTesting(child_layer_->id()));
+
+    child_layer_->SetIsDrawable(true);
+    child_layer_->SetHitTestable(true);
+    child_layer_->SetElementId(
+        LayerIdToElementIdForTesting(child_layer_->id()));
+    child_layer_->SetBounds(root_scroll_layer->bounds());
+    root_layer->AddChild(child_layer_);
+
+    CopyProperties(root_scroll_layer, child_layer_.get());
+    CreateTransformNode(child_layer_.get());
+    CreateScrollNode(child_layer_.get(), root_layer->bounds());
+    client_.set_bounds(root_scroll_layer->bounds());
+    client_.set_fill_with_nonsolid_color(true);
+    client_.set_has_draw_text_op();
+    child_layer_id_ = child_layer_->id();
+  }
+
+  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+  void WillCommit(const CommitState&) override {
+    TransformTree& transform_tree =
+        layer_tree_host()->property_trees()->transform_tree_mutable();
+
+    gfx::Transform transform;
+    switch (layer_tree_host()->SourceFrameNumber()) {
+      case 0:
+        transform.Scale(initial_scale_.x(), initial_scale_.y());
+        transform_tree.OnTransformAnimated(child_layer_->element_id(),
+                                           transform);
+        break;
+      case 1:
+        transform.Scale(new_scale_.x(), new_scale_.y());
+        transform_tree.OnTransformAnimated(child_layer_->element_id(),
+                                           transform);
+        break;
+    }
+  }
+
+  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+    if (host_impl->active_tree()->source_frame_number() == 1) {
+      FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>(
+          host_impl->active_tree()->LayerById(child_layer_id_));
+      gfx::AxisTransform2d tiling_transform =
+          target_layer->HighResTiling()->raster_transform();
+
+      if (host_impl->GetActivelyScrollingType() !=
+          ActivelyScrollingType::kNone) {
+        // In active tree, recreating the delayed tiling should not happen
+        ASSERT_EQ(tiling_transform.scale(), initial_scale_);
+
+        // stop scroll to check if recreating tiling happen in active tree
+        scroll_check_pending_ = false;
+        host_impl->GetInputHandler().ScrollEnd();
+        // make sure redraw happen
+        host_impl->active_tree()->set_needs_update_draw_properties();
+        host_impl->SetNeedsRedraw();
+      }
+    }
+  }
+
+  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+    FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>(
+        host_impl->active_tree()->LayerById(child_layer_id_));
+    gfx::AxisTransform2d tiling_transform =
+        target_layer->HighResTiling()->raster_transform();
+
+    switch (host_impl->active_tree()->source_frame_number()) {
+      case 0:
+        // start scroll
+        host_impl->GetInputHandler().ScrollBegin(
+            BeginState(gfx::Point(0, 0), gfx::Vector2dF(0, 10)).get(),
+            ui::ScrollInputType::kTouchscreen);
+        host_impl->GetInputHandler().ScrollUpdate(
+            UpdateState(gfx::Point(), gfx::Vector2dF(0, 10)).get());
+        scroll_check_pending_ = true;
+        PostSetNeedsCommitToMainThread();
+        break;
+
+      case 1:
+        if (host_impl->GetActivelyScrollingType() !=
+            ActivelyScrollingType::kNone) {
+          // In pending tree, recreating tiling should delayed during scroll
+          ASSERT_TRUE(scroll_check_pending_);
+          ASSERT_EQ(tiling_transform.scale(), initial_scale_);
+          host_impl->SetNeedsRedraw();
+        } else {
+          // recreating tiling should happen after scroll finish
+          ASSERT_FALSE(scroll_check_pending_);
+          ASSERT_EQ(tiling_transform.scale(), new_scale_);
+          EndTest();
+        }
+        break;
+    }
+  }
+
+ private:
+  scoped_refptr<FakePictureLayer> child_layer_;
+  int child_layer_id_;
+  FakeContentLayerClient client_;
+  bool scroll_check_pending_ = true;
+  const gfx::Vector2dF initial_scale_;
+  const gfx::Vector2dF new_scale_;
+};
+
+MULTI_THREAD_TEST_F(PreventRecreatingTilingDuringScroll);
 }  // namespace
 }  // namespace cc
diff --git a/chrome/VERSION b/chrome/VERSION
index 1e89066..72032bd 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=105
 MINOR=0
-BUILD=5123
+BUILD=5124
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 775733e..05935ae 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -338,6 +338,7 @@
     "$google_play_services_package:google_play_services_tasks_java",
     "$google_play_services_package:google_play_services_vision_common_java",
     "$google_play_services_package:google_play_services_vision_java",
+    "//base:jni_java",
     "//cc:cc_java",
     "//chrome/android/features/keyboard_accessory:public_java",
     "//chrome/android/features/start_surface:java_resources",
@@ -364,7 +365,6 @@
     "//chrome/browser/browser_controls/android:java",
     "//chrome/browser/commerce/android:java",
     "//chrome/browser/commerce/merchant_viewer/android:java",
-    "//chrome/browser/commerce/price_tracking/android:java",
     "//chrome/browser/commerce/price_tracking/proto:proto_java",
     "//chrome/browser/commerce/shopping_list/android:java",
     "//chrome/browser/commerce/subscriptions/android:java",
@@ -742,6 +742,7 @@
   # TODO(crbug/1186003): Instead of adding source files, add it as a separate
   # dependency when circular deps is resolved.
   sources += price_tracking_java_sources
+  deps += price_tracking_java_deps
 
   # TODO(crbug/1210158): Instead of adding source files, add it as a separate
   # dependency when circular deps is resolved.
@@ -986,7 +987,7 @@
     "//chrome/browser/browser_controls/android:java",
     "//chrome/browser/browser_controls/android:junit",
     "//chrome/browser/commerce/merchant_viewer/android:junit",
-    "//chrome/browser/commerce/price_tracking/android:java",
+    "//chrome/browser/commerce/price_tracking/android:public_java",
     "//chrome/browser/commerce/price_tracking/proto:proto_java",
     "//chrome/browser/commerce/subscriptions/android:java",
     "//chrome/browser/contextmenu:java",
@@ -1233,6 +1234,7 @@
   testonly = true
 
   sources = [
+    "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerWrapper.java",
     "javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java",
     "javatests/src/org/chromium/chrome/browser/homepage/HomepageTestRule.java",
     "javatests/src/org/chromium/chrome/browser/tabmodel/TestTabModelDirectory.java",
@@ -1313,12 +1315,16 @@
     "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRowTest.java",
     "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRowTest.java",
     "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkUtilsTest.java",
+    "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBaseTest.java",
+    "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java",
+    "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java",
     "javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java",
     "javatests/src/org/chromium/chrome/browser/crypto/CipherFactoryTest.java",
     "javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java",
     "javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java",
     "javatests/src/org/chromium/chrome/browser/firstrun/FirstRunUtilsTest.java",
     "javatests/src/org/chromium/chrome/browser/init/FirstDrawDetectorTest.java",
+    "javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java",
     "javatests/src/org/chromium/chrome/browser/tab/WebContentsStateBridgeTest.java",
     "javatests/src/org/chromium/chrome/browser/tabmodel/AsyncTabCreationParamsManagerTest.java",
     "javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java",
@@ -1333,6 +1339,7 @@
     "//chrome/android:chrome_java",
     "//chrome/android/features/autofill_assistant:unit_test_java",
     "//chrome/browser/android/crypto:java",
+    "//chrome/browser/commerce/subscriptions/android:java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/first_run/android:java",
     "//chrome/browser/flags:java",
@@ -1371,8 +1378,10 @@
     "//third_party/android_deps:guava_android_java",
     "//third_party/android_sdk:android_test_base_java",
     "//third_party/android_support_test_runner:runner_java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/blink/public:blink_headers_java",
+    "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
@@ -1430,7 +1439,8 @@
     "//chrome/browser/commerce/android:javatests",
     "//chrome/browser/commerce/merchant_viewer/android:java",
     "//chrome/browser/commerce/merchant_viewer/android:javatests",
-    "//chrome/browser/commerce/price_tracking/android:java",
+    "//chrome/browser/commerce/price_tracking/android:public_java",
+    "//chrome/browser/commerce/subscriptions/android:java",
     "//chrome/browser/content_creation/notes/internal/android:java",
     "//chrome/browser/content_creation/notes/internal/android:javatests",
     "//chrome/browser/contextmenu:java",
@@ -1555,7 +1565,7 @@
     "//components/browser_ui/display_cutout/android:java",
     "//components/browser_ui/media/android:java",
     "//components/browser_ui/modaldialog/android:java",
-    "//components/browser_ui/modaldialog/android:javatests",
+    "//components/browser_ui/modaldialog/android:test_support_java",
     "//components/browser_ui/notifications/android:java",
     "//components/browser_ui/notifications/android:test_support_java",
     "//components/browser_ui/photo_picker/android:javatests",
@@ -1609,7 +1619,6 @@
     "//components/media_router/browser/android:test_support_java",
     "//components/messages/android:java",
     "//components/messages/android/internal:java",
-    "//components/messages/android/internal:javatests",
     "//components/messages/android/test:test_support_java",
     "//components/metrics:metrics_java",
     "//components/minidump_uploader:minidump_uploader_java",
@@ -3148,13 +3157,16 @@
     "//chrome/android/features/tab_ui:unit_device_javatests",
     "//chrome/browser/back_press/android:unit_device_javatests",
     "//chrome/browser/loading_modal/android:unit_device_javatests",
+    "//chrome/browser/optimization_guide/android:unit_device_javatests",
     "//chrome/browser/partnercustomizations:unit_device_javatests",
     "//chrome/browser/ui/android/appmenu/internal:unit_device_javatests",
     "//chrome/browser/ui/messages/android:unit_device_javatests",
     "//chrome/browser/user_education:unit_device_javatests",
     "//chrome/browser/video_tutorials/internal:unit_device_javatests",
+    "//components/browser_ui/modaldialog/android:unit_device_javatests",
     "//components/browser_ui/widget/android:unit_device_javatests",
     "//components/embedder_support/android:embedder_support_javatests",
+    "//components/messages/android/internal:unit_device_javatests",
     "//components/paint_preview/player/android:javatests",
     "//components/signin/public/android:unit_device_javatests",
     "//components/strictmode/android:unit_device_javatests",
diff --git a/chrome/android/chrome_common_shared_library.gni b/chrome/android/chrome_common_shared_library.gni
index b0d76796..af086592 100644
--- a/chrome/android/chrome_common_shared_library.gni
+++ b/chrome/android/chrome_common_shared_library.gni
@@ -30,7 +30,6 @@
 #      native_deps. See //chrome/android/modules/chrome_feature_modules.gni for
 #      the descriptor format.
 template("chrome_common_shared_library") {
-  forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
   _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome
   _is_webview = defined(invoker.is_webview) && invoker.is_webview
   _export_java_symbols = _is_monochrome || _is_webview
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index c091c9c..508f357b 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -67,7 +67,9 @@
   "junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/layouts/SceneOverlayTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java",
+  "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
+  "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabUsageTrackerTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TestTabModel.java",
   "junit/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserverTest.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index 36135d11..e4cd77c 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -11,6 +11,7 @@
 import("//build/config/compiler/compiler.gni")
 import("//build/config/locales.gni")
 import("//build/util/version.gni")
+import("//chrome/android/chrome_common_shared_library.gni")
 import("//chrome/android/features/dev_ui/dev_ui_module.gni")
 import("//chrome/android/modules/chrome_bundle_tmpl.gni")
 import("//chrome/common/features.gni")
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 0d95e72..5d483a8 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -102,10 +102,6 @@
   "javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java",
   "javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentTest.java",
   "javatests/src/org/chromium/chrome/browser/compositor/CompositorVisibilityTest.java",
-  "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBaseTest.java",
-  "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java",
-  "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerTest.java",
-  "javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManagerWrapper.java",
   "javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutHost.java",
   "javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java",
@@ -322,7 +318,6 @@
   "javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/status/StatusMediatorUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewRenderTest.java",
-  "javatests/src/org/chromium/chrome/browser/omnibox/status/StatusViewTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java",
@@ -506,7 +501,6 @@
   "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java",
   "javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java",
-  "javatests/src/org/chromium/chrome/browser/survey/SurveyHttpClientBridgeTest.java",
   "javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java",
   "javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java",
   "javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
diff --git a/chrome/android/expectations/monochrome_public_bundle__base.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle__base.AndroidManifest.expected
index 0929e60..15995e5 100644
--- a/chrome/android/expectations/monochrome_public_bundle__base.AndroidManifest.expected
+++ b/chrome/android/expectations/monochrome_public_bundle__base.AndroidManifest.expected
@@ -436,24 +436,24 @@
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
     </activity>  # DIFF-ANCHOR: e86e2b49
-    <activity  # DIFF-ANCHOR: 01e92ad4
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$DismissNotificationChromeActivity"
+    <activity  # DIFF-ANCHOR: 7ff74272
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$DismissNotificationChromeActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 01e92ad4
-    <activity  # DIFF-ANCHOR: 24aedc77
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$TrampolineActivity"
+    </activity>  # DIFF-ANCHOR: 7ff74272
+    <activity  # DIFF-ANCHOR: 71702606
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$TrampolineActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 24aedc77
+    </activity>  # DIFF-ANCHOR: 71702606
     <activity  # DIFF-ANCHOR: 7468a722
         android:name="org.chromium.chrome.browser.searchwidget.SearchActivity"
         android:clearTaskOnLaunch="true"
diff --git a/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected
index 6712c46..6f214c1 100644
--- a/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected
+++ b/chrome/android/expectations/monochrome_public_bundle__chrome.AndroidManifest.expected
@@ -309,24 +309,24 @@
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
     </activity>  # DIFF-ANCHOR: e86e2b49
-    <activity  # DIFF-ANCHOR: 01e92ad4
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$DismissNotificationChromeActivity"
+    <activity  # DIFF-ANCHOR: 7ff74272
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$DismissNotificationChromeActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 01e92ad4
-    <activity  # DIFF-ANCHOR: 24aedc77
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$TrampolineActivity"
+    </activity>  # DIFF-ANCHOR: 7ff74272
+    <activity  # DIFF-ANCHOR: 71702606
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$TrampolineActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 24aedc77
+    </activity>  # DIFF-ANCHOR: 71702606
     <activity  # DIFF-ANCHOR: 7468a722
         android:name="org.chromium.chrome.browser.searchwidget.SearchActivity"
         android:clearTaskOnLaunch="true"
diff --git a/chrome/android/expectations/trichrome_chrome_bundle__base.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_bundle__base.AndroidManifest.expected
index 8c415e3..ab99d4064 100644
--- a/chrome/android/expectations/trichrome_chrome_bundle__base.AndroidManifest.expected
+++ b/chrome/android/expectations/trichrome_chrome_bundle__base.AndroidManifest.expected
@@ -409,24 +409,24 @@
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
     </activity>  # DIFF-ANCHOR: e86e2b49
-    <activity  # DIFF-ANCHOR: 01e92ad4
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$DismissNotificationChromeActivity"
+    <activity  # DIFF-ANCHOR: 7ff74272
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$DismissNotificationChromeActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 01e92ad4
-    <activity  # DIFF-ANCHOR: 24aedc77
-        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$TrampolineActivity"
+    </activity>  # DIFF-ANCHOR: 7ff74272
+    <activity  # DIFF-ANCHOR: 71702606
+        android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$TrampolineActivity"
         android:autoRemoveFromRecents="true"
         android:documentLaunchMode="always"
         android:excludeFromRecents="true"
         android:exported="false"
         android:noHistory="true"
         android:theme="@style/Theme.BrowserUI.NoDisplay">
-    </activity>  # DIFF-ANCHOR: 24aedc77
+    </activity>  # DIFF-ANCHOR: 71702606
     <activity  # DIFF-ANCHOR: 7468a722
         android:name="org.chromium.chrome.browser.searchwidget.SearchActivity"
         android:clearTaskOnLaunch="true"
diff --git a/chrome/android/features/android_library_factory/BUILD.gn b/chrome/android/features/android_library_factory/BUILD.gn
index 0044c32..e72df12 100644
--- a/chrome/android/features/android_library_factory/BUILD.gn
+++ b/chrome/android/features/android_library_factory/BUILD.gn
@@ -70,7 +70,6 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
   sources = [ "junit/src/org/chromium/chrome/browser/android_library_factory/AndroidLibraryFactoryTest.java" ]
   deps = [
     ":a_factory2_java",
@@ -78,7 +77,6 @@
     ":z_factory1_java",
     ":z_impl_factory2_java",
     "//testing/android/junit:junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/chrome/android/features/cablev2_authenticator/BUILD.gn b/chrome/android/features/cablev2_authenticator/BUILD.gn
index 6df6b7f3d..2370e7a6 100644
--- a/chrome/android/features/cablev2_authenticator/BUILD.gn
+++ b/chrome/android/features/cablev2_authenticator/BUILD.gn
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/android/rules.gni")
-import("//chrome/android/modules/buildflags.gni")
+import("//chrome/android/chrome_common_shared_library.gni")
 
 android_library("java") {
   sources = [
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index d45021b..0bb8dfdf 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -503,7 +503,6 @@
     @Test
     @MediumTest
     @Feature({"StartSurface"})
-    @DisabledTest(message = "https://crbug.com/1119322")
     @CommandLineFlags.Add({START_SURFACE_TEST_BASE_PARAMS + "/open_ntp_instead_of_start/true"})
     public void testHomeButton_OpenNTPInsteadOfStart() {
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn
index 802453e..7b0d2e3 100644
--- a/chrome/android/features/tab_ui/BUILD.gn
+++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -180,7 +180,7 @@
     "//chrome/browser/android/lifecycle:java",
     "//chrome/browser/back_press/android:java",
     "//chrome/browser/browser_controls/android:java",
-    "//chrome/browser/commerce/price_tracking/android:java",
+    "//chrome/browser/commerce/price_tracking/android:public_java",
     "//chrome/browser/endpoint_fetcher:java",
     "//chrome/browser/feature_engagement:java",
     "//chrome/browser/feed/android:java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java
index 12431e7d..bbeb8d9 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceMessageCardViewModel.java
@@ -107,4 +107,4 @@
         }
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceAlertsMessageCardTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceAlertsMessageCardTest.java
index 4a19fb22..8ec44e8 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceAlertsMessageCardTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceAlertsMessageCardTest.java
@@ -57,6 +57,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
 import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingUtilities;
 import org.chromium.chrome.browser.tasks.tab_management.MessageService.MessageDisableReason;
@@ -107,7 +108,7 @@
         Intents.init();
         PriceTrackingFeatures.setIsSignedInAndSyncEnabledForTesting(true);
         mMockNotificationManager = new MockNotificationManagerProxy();
-        PriceDropNotificationManager.setNotificationManagerForTesting(mMockNotificationManager);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(mMockNotificationManager);
         mPriceDropNotificationManager = PriceDropNotificationManagerFactory.create();
 
         mActivityTestRule.startMainActivityOnBlankPage();
@@ -121,7 +122,7 @@
             mPriceDropNotificationManager.deleteChannelForTesting();
         }
         PriceTrackingFeatures.setIsSignedInAndSyncEnabledForTesting(null);
-        PriceDropNotificationManager.setNotificationManagerForTesting(null);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(null);
         ActivityTestUtils.clearActivityOrientation(mActivityTestRule.getActivity());
         Intents.release();
     }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 3bcbcdb5..2dfc889a 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -1129,7 +1129,7 @@
             android:noHistory="true"/>
 
         <activity
-            android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$TrampolineActivity"
+            android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$TrampolineActivity"
             android:theme="@style/Theme.BrowserUI.NoDisplay"
             android:exported="false"
             android:autoRemoveFromRecents="true"
@@ -1138,7 +1138,7 @@
             android:noHistory="true"/>
 
         <activity
-            android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager$DismissNotificationChromeActivity"
+            android:name="org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl$DismissNotificationChromeActivity"
             android:theme="@style/Theme.BrowserUI.NoDisplay"
             android:exported="false"
             android:autoRemoveFromRecents="true"
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
index 0f0cc6a..74c3041 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
@@ -33,7 +33,6 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.app.metrics.LaunchCauseMetrics;
@@ -223,11 +222,11 @@
     }
 
     /**
-     * Test whether a custom tab can be reparented to a new activity while showing a select popup.
+     * Test whether a custom tab can be reparented to a new activity and the select element is
+     * still interactable after reparenting.
      */
-    // @SmallTest
+    @SmallTest
     @Test
-    @DisabledTest(message = "Flaky on browser_side_navigation apk - see crbug.com/707766")
     public void testTabReparentingSelectPopup() throws TimeoutException {
         LocationSettingsTestUtil.setSystemLocationSettingEnabled(true);
         mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
@@ -239,10 +238,13 @@
             Criteria.checkThat(currentTab, Matchers.notNullValue());
             Criteria.checkThat(currentTab.getWebContents(), Matchers.notNullValue());
         });
+
         DOMUtils.clickNode(mCustomTabActivityTestRule.getWebContents(), "select");
         CriteriaHelper.pollUiThread(
                 () -> isSelectPopupVisible(mCustomTabActivityTestRule.getActivity()));
+
         final ChromeActivity newActivity = reparentAndVerifyTab();
+        DOMUtils.clickNode(newActivity.getActivityTab().getWebContents(), "select");
         CriteriaHelper.pollUiThread(() -> isSelectPopupVisible(newActivity));
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java
index a2b12fd..def127be 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java
@@ -49,6 +49,7 @@
 import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.base.Clipboard;
+import org.chromium.ui.base.ClipboardAndroidTestSupport;
 import org.chromium.ui.base.ClipboardImpl;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.url.GURL;
@@ -169,7 +170,7 @@
             ((ClipboardImpl) Clipboard.getInstance())
                     .overrideClipboardManagerForTesting(mOldClipboardManager);
         });
-        Clipboard.cleanupForTesting();
+        ClipboardAndroidTestSupport.cleanup();
     }
 
     /** Test that the suggestion is triggered. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
index 6deaf21..021f368d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
@@ -206,7 +206,6 @@
     @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.START_SURFACE_ANDROID + "<Study",
             "force-fieldtrials=Study/Group",
             "force-fieldtrial-params=Study.Group:start_surface_variation/single"})
-    @DisabledTest(message = "https://crbug.com/1331065")
     public void testShowAndHideOnStartSurface() {
         // clang-format on
         TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/SurveyHttpClientBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/SurveyHttpClientBridgeTest.java
deleted file mode 100644
index a40bbd5..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/SurveyHttpClientBridgeTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2021 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.chrome.browser.survey;
-
-import android.content.Context;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Consumer;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.survey.SurveyHttpClientBridge.HttpResponse;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServer;
-import org.chromium.url.GURL;
-
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Integration test for {@link SurveyHttpClientBridge}.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class SurveyHttpClientBridgeTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/simple.html";
-
-    @Rule
-    public ChromeBrowserTestRule mTestRule = new ChromeBrowserTestRule();
-
-    private Context mContext;
-    private EmbeddedTestServer mTestServer;
-    private SurveyHttpClientBridge mHttpClient;
-
-    private Consumer<HttpResponse> mConsumer;
-
-    public HttpResponse mLastAcceptedResponse;
-
-    private final CallbackHelper mCallbackHelper = new CallbackHelper();
-
-    @Before
-    public void setUp() throws ExecutionException {
-        mContext = ContextUtils.getApplicationContext();
-        mTestServer = EmbeddedTestServer.createAndStartServer(mContext);
-        mConsumer = response -> {
-            mLastAcceptedResponse = response;
-            mCallbackHelper.notifyCalled();
-        };
-
-        TestThreadUtils.runOnUiThreadBlocking(
-                ()
-                        -> mHttpClient = new SurveyHttpClientBridge(
-                                   HttpClientType.SURVEY, Profile.getLastUsedRegularProfile()));
-    }
-
-    @Test
-    @SmallTest
-    public void testSendRequest() throws TimeoutException {
-        String url = mTestServer.getURL(TEST_PAGE);
-        GURL gurl = new GURL(url);
-        String body = "";
-
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> mHttpClient.send(gurl, "POST", body.getBytes(), new HashMap<>(), mConsumer));
-
-        mCallbackHelper.waitForFirst();
-        Assert.assertNotNull(mLastAcceptedResponse);
-    }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java
new file mode 100644
index 0000000..46609f43
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java
@@ -0,0 +1,143 @@
+// 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.chrome.browser.compositor.overlays.strip;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.flags.CachedFeatureFlags;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.ui.base.LocalizationUtils;
+
+/** Tests for {@link ScrollingStripStacker}. */
+@RunWith(BaseRobolectricTestRunner.class)
+public final class ScrollingStripStackerUnitTest {
+    private static final float TAB_OFFSET_Y = 2;
+    private static final float TAB_WIDTH = 25;
+    private static final float CACHED_TAB_WIDTH = 30;
+    private static final float STRIP_WIDTH = 200;
+    private static final float TAB_OVERLAP = 5;
+    private static final float STRIP_MARGIN = 2;
+    private static final float BUTTON_WIDTH = 10;
+
+    private ScrollingStripStacker mTarget = new ScrollingStripStacker();
+    @Mock
+    private StripLayoutTab mTab1;
+    @Mock
+    private StripLayoutTab mTab2;
+    @Mock
+    private StripLayoutTab mTab3;
+    @Mock
+    private StripLayoutTab mTab4;
+    @Mock
+    private StripLayoutTab mTab5;
+    private StripLayoutTab[] mInput;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mInput = new StripLayoutTab[] {mTab1, mTab2, mTab3, mTab4, mTab5};
+        float ideal_x = 0;
+        // First and last tab out of visible area.
+        float draw_x = -TAB_WIDTH - 1;
+        for (StripLayoutTab tab : mInput) {
+            when(tab.getIdealX()).thenReturn(ideal_x);
+            when(tab.getOffsetY()).thenReturn(TAB_OFFSET_Y);
+            when(tab.getWidth()).thenReturn(TAB_WIDTH);
+            when(tab.getDrawX()).thenReturn(draw_x);
+            draw_x += TAB_WIDTH;
+            ideal_x += TAB_WIDTH;
+        }
+        setTabStripImprovementFeature(false);
+    }
+
+    @Test
+    public void testSetTabOffsets() {
+        mTarget.setTabOffsets(2, mInput, 0, 0, 0, 0, 0, 0, false, false, CACHED_TAB_WIDTH);
+
+        float expected_x = 0;
+        for (StripLayoutTab tab : mInput) {
+            verify(tab).setDrawX(expected_x);
+            verify(tab).setDrawY(TAB_OFFSET_Y);
+            verify(tab).setVisiblePercentage(1.f);
+            verify(tab).setContentOffsetX(0.f);
+            expected_x += TAB_WIDTH;
+        }
+    }
+
+    @Test
+    public void testSetTabOffsets_withTabStripImprovement_tabNotClosing() {
+        setTabStripImprovementFeature(true);
+
+        mTarget.setTabOffsets(2, mInput, 0, 0, 0, 0, 0, 0, false, false, CACHED_TAB_WIDTH);
+
+        float expected_x = 0;
+        for (StripLayoutTab tab : mInput) {
+            verify(tab).setDrawX(expected_x);
+            verify(tab).setWidth(CACHED_TAB_WIDTH);
+            verify(tab).setDrawY(TAB_OFFSET_Y);
+            verify(tab).setVisiblePercentage(1.f);
+            verify(tab).setContentOffsetX(0.f);
+            expected_x += TAB_WIDTH;
+        }
+    }
+
+    @Test
+    public void testSetTabOffsets_withTabStripImprovement_tabClosing() {
+        setTabStripImprovementFeature(true);
+
+        mTarget.setTabOffsets(2, mInput, 0, 0, 0, 0, 0, STRIP_WIDTH, false, true, CACHED_TAB_WIDTH);
+
+        for (StripLayoutTab tab : mInput) {
+            verify(tab).setDrawY(TAB_OFFSET_Y);
+            verify(tab).setVisiblePercentage(1.f);
+            verify(tab).setContentOffsetX(0.f);
+            verify(tab).getOffsetY();
+            verifyNoMoreInteractions(tab);
+        }
+    }
+
+    @Test
+    public void testPerformOcclusionPass() {
+        mTarget.performOcclusionPass(2, mInput, 2 * TAB_WIDTH);
+
+        for (StripLayoutTab tab : mInput) {
+            if (tab == mTab1 || tab == mTab5) {
+                verify(tab).setVisible(false);
+            } else {
+                verify(tab).setVisible(true);
+            }
+        }
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffset() {
+        float value = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_MARGIN,
+                STRIP_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, 0, CACHED_TAB_WIDTH, true);
+        assertThat("Button offset does not match", value, is(96.5f));
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffsetRTL() {
+        LocalizationUtils.setRtlForTesting(true);
+        float value = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_MARGIN,
+                STRIP_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, 0, CACHED_TAB_WIDTH, true);
+        assertThat("Button offset does not match", value, is(66.5f));
+    }
+
+    private void setTabStripImprovementFeature(boolean value) {
+        CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_STRIP_IMPROVEMENTS, value);
+    }
+}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
new file mode 100644
index 0000000..fbc338d8
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
@@ -0,0 +1,151 @@
+// 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.chrome.browser.compositor.overlays.strip;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.flags.CachedFeatureFlags;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.ui.base.LocalizationUtils;
+
+/** Tests for {@link StripStacker}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.M, qualifiers = "sw600dp")
+public class StripStackerUnitTest {
+    private static final float TAB_WIDTH = 25;
+    private static final float CACHED_TAB_WIDTH = 30;
+    private static final float TAB_WEIGHT = 1;
+    private static final float TAB_OVERLAP = 5;
+    private static final float STRIP_LEFT_MARGIN = 2;
+    private static final float STRIP_RIGHT_MARGIN = 2;
+    private static final float STRIP_WIDTH = 200;
+    private static final float BUTTON_WIDTH = 10;
+    private static final float TOUCH_OFFSET = 5;
+
+    private StripStacker mTarget = new DummyStacker();
+
+    @Mock
+    private StripLayoutTab mTab1;
+    @Mock
+    private StripLayoutTab mTab2;
+    @Mock
+    private StripLayoutTab mTab3;
+    @Mock
+    private StripLayoutTab mTab4;
+    @Mock
+    private StripLayoutTab mTab5;
+    private StripLayoutTab[] mInput;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mInput = new StripLayoutTab[] {mTab1, mTab2, mTab3, mTab4, mTab5};
+        float x = 0;
+        for (StripLayoutTab tab : mInput) {
+            when(tab.getWidth()).thenReturn(TAB_WIDTH);
+            when(tab.getWidthWeight()).thenReturn(TAB_WEIGHT);
+            when(tab.getDrawX()).thenReturn(x);
+            x += TAB_WIDTH;
+        }
+        setTabStripImprovementFeature(false);
+    }
+
+    @After
+    public void tearDown() {
+        setTabStripImprovementFeature(false);
+    }
+
+    @Test
+    public void testCreateVisualOrdering() {
+        final StripLayoutTab[] output = new StripLayoutTab[mInput.length];
+        final StripLayoutTab[] expected_output =
+                new StripLayoutTab[] {mTab1, mTab2, mTab5, mTab4, mTab3};
+
+        mTarget.createVisualOrdering(2, mInput, output);
+        assertThat("Visual ordering does not match", output, equalTo(expected_output));
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffset() {
+        float result = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_LEFT_MARGIN,
+                STRIP_RIGHT_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, TOUCH_OFFSET, CACHED_TAB_WIDTH,
+                true);
+        assertThat("New Tab button offset does not match", result, is(130f));
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffset_withTabStripImprovements() {
+        setTabStripImprovementFeature(true);
+        float result = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_LEFT_MARGIN,
+                STRIP_RIGHT_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, TOUCH_OFFSET, CACHED_TAB_WIDTH,
+                true);
+        assertThat("New Tab button offset does not match", result, is(35f));
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffsetRTL() {
+        LocalizationUtils.setRtlForTesting(true);
+        float expected_res = 3f;
+        // Update drawX for RTL = ((mInput.length -1 ) * TAB_WIDTH) + TOUCH_OFFSET + BUTTON_WIDTH
+        // +expected_res = 4*25 + 5 + 10 +3
+        float draw_x = 118f;
+        for (StripLayoutTab tab : mInput) {
+            when(tab.getDrawX()).thenReturn(draw_x);
+            draw_x -= TAB_WIDTH;
+        }
+        float result = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_LEFT_MARGIN,
+                STRIP_RIGHT_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, TOUCH_OFFSET, CACHED_TAB_WIDTH,
+                true);
+        assertThat("New Tab button offset does not match", result, is(expected_res));
+    }
+
+    @Test
+    public void testComputeNewTabButtonOffsetRTL_withTabStripImprovements() {
+        LocalizationUtils.setRtlForTesting(true);
+        setTabStripImprovementFeature(true);
+        float expected_res = 3f;
+        // Update idealX for RTL = ((mInput.length -1 ) * TAB_WIDTH) + TOUCH_OFFSET + BUTTON_WIDTH +
+        // expected_res = 4*25 + 5 + 10 + 3
+        float ideal_x = 118f;
+        for (StripLayoutTab tab : mInput) {
+            when(tab.getIdealX()).thenReturn(ideal_x);
+            ideal_x -= TAB_WIDTH;
+        }
+        float result = mTarget.computeNewTabButtonOffset(mInput, TAB_OVERLAP, STRIP_LEFT_MARGIN,
+                STRIP_RIGHT_MARGIN, STRIP_WIDTH, BUTTON_WIDTH, TOUCH_OFFSET, CACHED_TAB_WIDTH,
+                true);
+        assertThat("New Tab button offset does not match", result, is(expected_res));
+    }
+
+    private void setTabStripImprovementFeature(boolean value) {
+        CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_STRIP_IMPROVEMENTS, value);
+    }
+
+    class DummyStacker extends StripStacker {
+        @Override
+        public void setTabOffsets(int selectedIndex, StripLayoutTab[] indexOrderedTabs,
+                float tabStackWidth, int maxTabsToStack, float tabOverlapWidth,
+                float stripLeftMargin, float stripRightMargin, float stripWidth,
+                boolean inReorderMode, boolean tabClosing, float cachedTabWidth) {}
+
+        @Override
+        public void performOcclusionPass(
+                int selectedIndex, StripLayoutTab[] indexOrderedTabs, float stripWidth) {}
+    }
+}
diff --git a/chrome/android/webapk/test/BUILD.gn b/chrome/android/webapk/test/BUILD.gn
index 015cc74..0c43ae11 100644
--- a/chrome/android/webapk/test/BUILD.gn
+++ b/chrome/android/webapk/test/BUILD.gn
@@ -5,11 +5,9 @@
 import("//build/config/android/rules.gni")
 
 robolectric_library("junit_test_support") {
-  testonly = true
   sources = [ "src/org/chromium/webapk/test/WebApkTestHelper.java" ]
   deps = [
     "//chrome/android/webapk/libs/common:common_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/app/chrome.cml b/chrome/app/chrome.cml
index 207e8b3..4ef8412 100644
--- a/chrome/app/chrome.cml
+++ b/chrome/app/chrome.cml
@@ -55,6 +55,7 @@
                 "fuchsia.device.NameProvider",
                 "fuchsia.element.GraphicalPresenter",
                 "fuchsia.fonts.Provider",
+                "fuchsia.hwinfo.Product",
                 "fuchsia.input.virtualkeyboard.ControllerCreator",
                 "fuchsia.intl.PropertyProvider",
                 "fuchsia.media.Audio",
diff --git a/chrome/app/chrome_v1.cmx b/chrome/app/chrome_v1.cmx
index a45fa78..cd376be 100644
--- a/chrome/app/chrome_v1.cmx
+++ b/chrome/app/chrome_v1.cmx
@@ -18,6 +18,7 @@
       "fuchsia.device.NameProvider",
       "fuchsia.element.GraphicalPresenter",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index e958565..040850c 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4218,13 +4218,10 @@
           Reload
         </message>
         <message name="IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE" desc="Title of the bubble to tell users that in order to run an extension, they'll need to refresh the page.">
-          Refresh the page to use "<ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph>"
+          Reload the page to use "<ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph>"
         </message>
-        <message name="IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON_LABEL" desc="The label of the button to proceed with the page refresh for running an extension.">
-          Refresh
-        </message>
-        <message name="IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_BODY_TEXT" desc="The body text of the bubble to tell users to check the checkbox to always allow the extensions to run on the current site.">
-          Always allow the extension to run on this site if you don't want to see this message again.
+        <message name="IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_UPDATE_PERMISSIONS_TITLE" desc="Title of the bubble to tell users that in order to change site permissions, they'll need to refresh the page.">
+          Reload the page to apply your changes
         </message>
         <message name="IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_CHECKBOX_LABEL" desc="The label of the checkbox to always allow the extensions to run on the current site.">
           Always allow on this site
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_BODY_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_BODY_TEXT.png.sha1
deleted file mode 100644
index b2e72ca..0000000
--- a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_BODY_TEXT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-2e1ac8a4ff62f65509e778e62d8c40347db6a7b0
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON_LABEL.png.sha1
deleted file mode 100644
index b2e72ca..0000000
--- a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-2e1ac8a4ff62f65509e778e62d8c40347db6a7b0
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE.png.sha1
index b2e72ca..f513ee8 100644
--- a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE.png.sha1
@@ -1 +1 @@
-2e1ac8a4ff62f65509e778e62d8c40347db6a7b0
\ No newline at end of file
+a5178af55de41f0deb75ce3f189f120871c664d5
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_UPDATE_PERMISSIONS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_UPDATE_PERMISSIONS_TITLE.png.sha1
new file mode 100644
index 0000000..e34b0caa
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_UPDATE_PERMISSIONS_TITLE.png.sha1
@@ -0,0 +1 @@
+71adcd3a7e5695f91d7a32b0a9287d71084b6403
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 24bd9cd..6a2d6324 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -2193,6 +2193,12 @@
   <message name="IDS_SETTINGS_BLUETOOTH_DISABLED_A11Y_LABEL" desc="Bluetooth device details page: Accessibility announcement when Bluetooth state is disabled.">
     Bluetooth disabled
   </message>
+  <message name="IDS_BLUETOOTH_SAVED_DEVICES_LABEL" desc="Label for the link row that directs to Saved Devices settings sub-page.">
+    Devices saved to your account
+  </message>
+  <message name="IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE" desc="Subtitle for the link row that directs to Saved Devices settings sub-page.">
+    Fast Pair devices saved to <ph name="PRIMARY_EMAIL">$1<ex>john@google.com</ex></ph>
+  </message>
 
 
   <!-- Parental Controls -->
diff --git a/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_LABEL.png.sha1
new file mode 100644
index 0000000..e624ab8
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_LABEL.png.sha1
@@ -0,0 +1 @@
+086bb4c84adaf4d2b4b3d0ce0d55ead50e4251b3
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE.png.sha1
new file mode 100644
index 0000000..e624ab8
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE.png.sha1
@@ -0,0 +1 @@
+086bb4c84adaf4d2b4b3d0ce0d55ead50e4251b3
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 990f7433..7f67af2c 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -7093,11 +7093,6 @@
      flag_descriptions::kNearbySharingOnePageOnboardingName,
      flag_descriptions::kNearbySharingOnePageOnboardingDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kNearbySharingOnePageOnboarding)},
-    {"nearby-sharing-receive-wifi-credentials",
-     flag_descriptions::kNearbySharingReceiveWifiCredentialsName,
-     flag_descriptions::kNearbySharingReceiveWifiCredentialsDescription,
-     kOsCrOS,
-     FEATURE_VALUE_TYPE(features::kNearbySharingReceiveWifiCredentials)},
     {"nearby-sharing-self-share-auto-accept",
      flag_descriptions::kNearbySharingSelfShareAutoAcceptName,
      flag_descriptions::kNearbySharingSelfShareAutoAcceptDescription, kOsCrOS,
diff --git a/chrome/browser/android/browserservices/intents/BUILD.gn b/chrome/browser/android/browserservices/intents/BUILD.gn
index e177d14f..4b89246 100644
--- a/chrome/browser/android/browserservices/intents/BUILD.gn
+++ b/chrome/browser/android/browserservices/intents/BUILD.gn
@@ -34,7 +34,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/chrome/browser/browserservices/intents/WebApkInfoTest.java",
     "java/src/org/chromium/chrome/browser/browserservices/intents/WebappInfoTest.java",
@@ -52,7 +51,6 @@
     "//components/webapk/android/libs/common:java",
     "//components/webapps/browser/android:java",
     "//services/device/public/mojom:mojom_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_browser_browser_java",
     "//third_party/blink/public/mojom:mojom_platform_java",
     "//third_party/hamcrest:hamcrest_library_java",
diff --git a/chrome/browser/android/browserservices/verification/BUILD.gn b/chrome/browser/android/browserservices/verification/BUILD.gn
index d2bcb48a..fac13f7 100644
--- a/chrome/browser/android/browserservices/verification/BUILD.gn
+++ b/chrome/browser/android/browserservices/verification/BUILD.gn
@@ -61,12 +61,10 @@
 }
 
 robolectric_library("junit_test_support") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/browserservices/verification/OriginVerifierUnitTestSupport.java" ]
   deps = [
     ":java",
     "//components/embedder_support/android:util_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_browser_browser_java",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/android/webapps/launchpad/BUILD.gn b/chrome/browser/android/webapps/launchpad/BUILD.gn
index ee3ffe8..4f53e10 100644
--- a/chrome/browser/android/webapps/launchpad/BUILD.gn
+++ b/chrome/browser/android/webapps/launchpad/BUILD.gn
@@ -70,8 +70,6 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/webapps/launchpad/AppManagementMenuPermissionsCoordinatorTest.java",
@@ -92,7 +90,6 @@
     "//components/content_settings/android:content_settings_enums_java",
     "//components/embedder_support/android:util_java",
     "//content/public/android:content_full_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc
index c79444d..077cdbbc 100644
--- a/chrome/browser/apps/app_service/intent_util.cc
+++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -628,6 +628,27 @@
 }
 
 base::flat_map<std::string, std::string> CreateArcIntentExtras(
+    const apps::IntentPtr& intent) {
+  auto extras = base::flat_map<std::string, std::string>();
+  if (intent->share_text.has_value()) {
+    // Slice off the "S." prefix for the key.
+    extras.insert(std::make_pair(kIntentExtraText + kIntentPrefixLength,
+                                 intent->share_text.value()));
+  }
+  if (intent->share_title.has_value()) {
+    // Slice off the "S." prefix for the key.
+    extras.insert(std::make_pair(kIntentExtraSubject + kIntentPrefixLength,
+                                 intent->share_title.value()));
+  }
+  if (intent->start_type.has_value()) {
+    // Slice off the "S." prefix for the key.
+    extras.insert(std::make_pair(kIntentExtraStartType + kIntentPrefixLength,
+                                 intent->start_type.value()));
+  }
+  return extras;
+}
+
+base::flat_map<std::string, std::string> CreateArcIntentExtras(
     const apps::mojom::IntentPtr& intent) {
   auto extras = base::flat_map<std::string, std::string>();
   if (intent->share_text.has_value()) {
@@ -649,6 +670,41 @@
 }
 
 arc::mojom::IntentInfoPtr ConvertAppServiceToArcIntent(
+    const apps::IntentPtr& intent) {
+  arc::mojom::IntentInfoPtr arc_intent;
+  if (!intent->url.has_value() && !intent->share_text.has_value() &&
+      !intent->activity_name.has_value()) {
+    return arc_intent;
+  }
+
+  arc_intent = arc::mojom::IntentInfo::New();
+  arc_intent->action = ConvertAppServiceToArcIntentAction(intent->action);
+  if (intent->url.has_value()) {
+    arc_intent->data = intent->url->spec();
+  }
+  if (intent->share_text.has_value() || intent->share_title.has_value() ||
+      intent->start_type.has_value()) {
+    arc_intent->extras = CreateArcIntentExtras(intent);
+  }
+  if (!intent->categories.empty()) {
+    arc_intent->categories = intent->categories;
+  }
+  if (intent->data.has_value()) {
+    arc_intent->data = intent->data;
+  }
+  if (intent->mime_type.has_value()) {
+    arc_intent->type = intent->mime_type;
+  }
+  if (intent->ui_bypassed.has_value()) {
+    arc_intent->ui_bypassed = intent->ui_bypassed.value();
+  }
+  if (!intent->extras.empty()) {
+    arc_intent->extras = intent->extras;
+  }
+  return arc_intent;
+}
+
+arc::mojom::IntentInfoPtr ConvertAppServiceToArcIntent(
     const apps::mojom::IntentPtr& intent) {
   arc::mojom::IntentInfoPtr arc_intent;
   if (!intent->url.has_value() && !intent->share_text.has_value() &&
@@ -774,7 +830,7 @@
 
 arc::IntentFilter ConvertAppServiceToArcIntentFilter(
     const std::string& package_name,
-    const apps::mojom::IntentFilterPtr& intent_filter) {
+    const apps::IntentFilterPtr& intent_filter) {
   std::vector<std::string> actions;
   std::vector<std::string> schemes;
   std::vector<arc::IntentFilter::AuthorityEntry> authorities;
@@ -782,53 +838,53 @@
   std::vector<std::string> mime_types;
   for (auto& condition : intent_filter->conditions) {
     switch (condition->condition_type) {
-      case apps::mojom::ConditionType::kScheme:
+      case apps::ConditionType::kScheme:
         for (auto& condition_value : condition->condition_values) {
           schemes.push_back(condition_value->value);
         }
         break;
-      case apps::mojom::ConditionType::kHost:
+      case apps::ConditionType::kHost:
         for (auto& condition_value : condition->condition_values) {
           authorities.emplace_back(
               /*host=*/condition_value->value, /*port=*/0);
         }
         break;
-      case apps::mojom::ConditionType::kPattern:
+      case apps::ConditionType::kPattern:
         for (auto& condition_value : condition->condition_values) {
           arc::mojom::PatternType match_type;
           switch (condition_value->match_type) {
-            case apps::mojom::PatternMatchType::kLiteral:
+            case apps::PatternMatchType::kLiteral:
               match_type = arc::mojom::PatternType::PATTERN_LITERAL;
               break;
-            case apps::mojom::PatternMatchType::kPrefix:
+            case apps::PatternMatchType::kPrefix:
               match_type = arc::mojom::PatternType::PATTERN_PREFIX;
               break;
-            case apps::mojom::PatternMatchType::kGlob:
+            case apps::PatternMatchType::kGlob:
               match_type = arc::mojom::PatternType::PATTERN_SIMPLE_GLOB;
               break;
-            case apps::mojom::PatternMatchType::kNone:
-            case apps::mojom::PatternMatchType::kMimeType:
-            case apps::mojom::PatternMatchType::kFileExtension:
-            case apps::mojom::PatternMatchType::kIsDirectory:
-            case apps::mojom::PatternMatchType::kSuffix:
+            case apps::PatternMatchType::kNone:
+            case apps::PatternMatchType::kMimeType:
+            case apps::PatternMatchType::kFileExtension:
+            case apps::PatternMatchType::kIsDirectory:
+            case apps::PatternMatchType::kSuffix:
               NOTREACHED();
               return arc::IntentFilter();
           }
           paths.emplace_back(condition_value->value, match_type);
         }
         break;
-      case apps::mojom::ConditionType::kAction:
+      case apps::ConditionType::kAction:
         for (auto& condition_value : condition->condition_values) {
           actions.push_back(
               ConvertAppServiceToArcIntentAction(condition_value->value));
         }
         break;
-      case apps::mojom::ConditionType::kMimeType:
+      case apps::ConditionType::kMimeType:
         for (auto& condition_value : condition->condition_values) {
           mime_types.push_back(condition_value->value);
         }
         break;
-      case apps::mojom::ConditionType::kFile:
+      case apps::ConditionType::kFile:
         NOTREACHED();
         return arc::IntentFilter();
     }
diff --git a/chrome/browser/apps/app_service/intent_util.h b/chrome/browser/apps/app_service/intent_util.h
index 9fece0e..1a691b5 100644
--- a/chrome/browser/apps/app_service/intent_util.h
+++ b/chrome/browser/apps/app_service/intent_util.h
@@ -138,10 +138,18 @@
     const std::string& share_title);
 
 base::flat_map<std::string, std::string> CreateArcIntentExtras(
+    const apps::IntentPtr& intent);
+// TODO(crbug.com/1253250): Will be removed soon. Please use the non mojom
+// interface.
+base::flat_map<std::string, std::string> CreateArcIntentExtras(
     const apps::mojom::IntentPtr& intent);
 
 // Convert between App Service and ARC Intents.
 arc::mojom::IntentInfoPtr ConvertAppServiceToArcIntent(
+    const apps::IntentPtr& intent);
+// TODO(crbug.com/1253250): Will be removed soon. Please use the non mojom
+// interface.
+arc::mojom::IntentInfoPtr ConvertAppServiceToArcIntent(
     const apps::mojom::IntentPtr& intent);
 
 // Converts an ARC intent action to an App Service intent action. Returns
@@ -158,7 +166,7 @@
 // Convert between App Service and ARC IntentFilters.
 arc::IntentFilter ConvertAppServiceToArcIntentFilter(
     const std::string& package_name,
-    const apps::mojom::IntentFilterPtr& intent_filter);
+    const apps::IntentFilterPtr& intent_filter);
 
 apps::IntentFilterPtr CreateIntentFilterForArc(
     const arc::IntentFilter& arc_intent_filter);
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc
index 14d7f7f1..1382473b 100644
--- a/chrome/browser/apps/app_service/intent_util_unittest.cc
+++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -137,6 +137,37 @@
   const std::string& activity_name = "com.android.vending.AssetBrowserActivity";
   const std::string& start_type = "initialStart";
   const std::string& category = "android.intent.category.LAUNCHER";
+  apps::IntentPtr intent =
+      apps_util::MakeIntentForActivity(activity_name, start_type, category);
+  arc::mojom::IntentInfoPtr arc_intent =
+      apps_util::ConvertAppServiceToArcIntent(intent);
+
+  ASSERT_TRUE(intent);
+  ASSERT_TRUE(arc_intent);
+
+  // TODO(crbug.com/1253250): Modify CreateLaunchIntent to use the non mojom
+  // intent to verity intent_str, done in CreateIntentForActivityMojom.
+
+  EXPECT_EQ(arc::kIntentActionMain, arc_intent->action);
+
+  base::flat_map<std::string, std::string> extras;
+  extras.insert(std::make_pair("org.chromium.arc.start_type", start_type));
+  EXPECT_TRUE(arc_intent->extras.has_value());
+  EXPECT_EQ(extras, arc_intent->extras);
+
+  EXPECT_TRUE(arc_intent->categories.has_value());
+  EXPECT_EQ(category, arc_intent->categories.value()[0]);
+
+  arc_intent->extras = apps_util::CreateArcIntentExtras(intent);
+  EXPECT_TRUE(intent->activity_name.has_value());
+  EXPECT_EQ(activity_name, intent->activity_name.value());
+}
+
+// TODO(crbug.com/1253250): Remove after migrating to non-mojo AppService.
+TEST_F(IntentUtilsTest, CreateIntentForActivityMojom) {
+  const std::string& activity_name = "com.android.vending.AssetBrowserActivity";
+  const std::string& start_type = "initialStart";
+  const std::string& category = "android.intent.category.LAUNCHER";
   apps::mojom::IntentPtr intent =
       apps_util::CreateIntentForActivity(activity_name, start_type, category);
   arc::mojom::IntentInfoPtr arc_intent =
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index 9e65ae7..94ed3b9 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -330,8 +330,9 @@
 
   instance->AddPreferredApp(
       package_name,
-      apps_util::ConvertAppServiceToArcIntentFilter(package_name,
-                                                    intent_filter),
+      apps_util::ConvertAppServiceToArcIntentFilter(
+          package_name,
+          apps::ConvertMojomIntentFilterToIntentFilter(intent_filter)),
       apps_util::ConvertAppServiceToArcIntent(std::move(intent)));
 }
 
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 12402bfbb..6b425a01d 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -1116,6 +1116,8 @@
     "floating_workspace/floating_workspace_util.h",
     "fusebox/fusebox_util.cc",
     "fusebox/fusebox_util.h",
+    "guest_os/guest_id.cc",
+    "guest_os/guest_id.h",
     "guest_os/guest_os_capabilities.cc",
     "guest_os/guest_os_capabilities.h",
     "guest_os/guest_os_diagnostics_builder.cc",
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
index 45ea981c..f9a49bd 100644
--- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
+++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
@@ -112,15 +112,12 @@
       ash::PillButton::Type::kIcon, &kTipIcon);
   nudge_view->SetSize(
       gfx::Size(nudge_view->GetPreferredSize().width(), kNudgeHeight));
-  nudge_view->SetButtonTextColor(GetContentLayerColor(
-      ash::AshColorProvider::ContentLayerType::kTextColorPrimary));
-  auto* color_provider = ash::AshColorProvider::Get();
-  DCHECK(color_provider);
-  // TODO(djacobo|cuicuiruan): Retrieve colors via a single provider.
-  nudge_view->SetBackgroundColor(color_provider->GetContentLayerColor(
-      ash::AshColorProvider::ContentLayerType::kButtonLabelColorBlue));
-  nudge_view->SetIconColor(GetContentLayerColor(
-      ash::AshColorProvider::ContentLayerType::kIconColorPrimary));
+  nudge_view->SetButtonTextColor(cros_styles::ResolveColor(
+      cros_styles::ColorName::kNudgeLabelColor, IsDarkModeEnabled()));
+  nudge_view->SetBackgroundColor(cros_styles::ResolveColor(
+      cros_styles::ColorName::kNudgeBackgroundColor, IsDarkModeEnabled()));
+  nudge_view->SetIconColor(cros_styles::ResolveColor(
+      cros_styles::ColorName::kNudgeIconColor, IsDarkModeEnabled()));
   nudge_view->SetPosition(CalculateNudgePosition(nudge_view->width()));
 
   auto* parent = overlay_widget->GetContentsView();
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
index e3846033..2f1bc1b 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_label.cc
@@ -243,11 +243,8 @@
   DCHECK(parent());
   auto code = event.code();
   auto* parent_view = static_cast<ActionView*>(parent());
-  if (base::UTF8ToUTF16(GetDisplayText(code)) == GetText()) {
-    SetDisplayMode(DisplayMode::kEditedError);
-  } else {
+  if (base::UTF8ToUTF16(GetDisplayText(code)) != GetText())
     parent_view->OnKeyBindingChange(this, code);
-  }
   return true;
 }
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
index b16955b..47dcdcc 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
@@ -88,7 +88,9 @@
     // UI's banner.
     const gfx::ImageSkia* skia_banner =
         ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-            IDS_ARC_INPUT_OVERLAY_ONBOARDING_ILLUSTRATION);
+            IsDarkModeEnabled()
+                ? IDS_ARC_INPUT_OVERLAY_ONBOARDING_ILLUSTRATION_DARK
+                : IDS_ARC_INPUT_OVERLAY_ONBOARDING_ILLUSTRATION);
     CHECK(skia_banner);
     auto banner = std::make_unique<views::ImageView>(
         ui::ImageModel::FromImageSkia(*skia_banner));
@@ -103,9 +105,9 @@
     container_view->SetLayoutManager(std::make_unique<views::FlexLayout>())
         ->SetOrientation(views::LayoutOrientation::kHorizontal)
         .SetMainAxisAlignment(views::LayoutAlignment::kCenter);
-    // Game control.
+    // Game controls.
     container_view->AddChildView(ash::login_views_utils::CreateBubbleLabel(
-        l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_EDUCATIONAL_TITLE_ALPHA),
+        l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA),
         /*view_defining_max_width=*/nullptr,
         /*color=*/
         GetContentLayerColor(
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_bridge.cc b/chrome/browser/ash/arc/tracing/arc_tracing_bridge.cc
index 4a88b36..d4452fb 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_bridge.cc
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_bridge.cc
@@ -100,6 +100,14 @@
 
  private:
   friend class base::NoDestructor<ArcTracingDataSource>;
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  using DataSourceProxy =
+      tracing::PerfettoTracedProcess::DataSourceProxy<CastDataSource>;
+  using SystemTraceWriter =
+      tracing::SystemTraceWriter<std::string, DataSourceProxy>;
+#else
+  using SystemTraceWriter = tracing::SystemTraceWriter<std::string>;
+#endif
 
   ArcTracingDataSource()
       : DataSourceBase(tracing::mojom::kArcTraceDataSourceName),
@@ -107,6 +115,11 @@
                                   ->GetTaskRunner()
                                   ->GetOrCreateTaskRunner()) {
     tracing::PerfettoTracedProcess::Get()->AddDataSource(this);
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+    perfetto::DataSourceDescriptor dsd;
+    dsd.set_name(mojom::kArcTraceDataSourceName);
+    DataSourceProxy::Register(dsd, this);
+#endif
   }
 
   // Note that ArcTracingDataSource is a singleton that's never destroyed.
@@ -261,7 +274,7 @@
   // we need to track it ourselves for access from the UI thread.
   tracing::PerfettoProducer* producer_on_ui_thread_ = nullptr;
   perfetto::DataSourceConfig data_source_config_;
-  std::unique_ptr<tracing::SystemTraceWriter<std::string>> trace_writer_;
+  std::unique_ptr<SystemTraceWriter> trace_writer_;
 };
 
 }  // namespace
diff --git a/chrome/browser/ash/crostini/ansible/ansible_management_service.cc b/chrome/browser/ash/crostini/ansible/ansible_management_service.cc
index bd2184c..1b5c0df4 100644
--- a/chrome/browser/ash/crostini/ansible/ansible_management_service.cc
+++ b/chrome/browser/ash/crostini/ansible/ansible_management_service.cc
@@ -49,7 +49,7 @@
 AnsibleManagementService::~AnsibleManagementService() = default;
 
 void AnsibleManagementService::ConfigureContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::FilePath playbook_path,
     base::OnceCallback<void(bool success)> callback) {
   if (configuration_tasks_.count(container_id) > 0) {
@@ -89,7 +89,7 @@
 }
 
 void AnsibleManagementService::OnInstallAnsibleInContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResult result) {
   if (result == CrostiniResult::INSTALL_LINUX_PACKAGE_FAILED) {
     LOG(ERROR) << "Ansible installation failed";
@@ -108,7 +108,7 @@
 }
 
 void AnsibleManagementService::OnInstallLinuxPackageProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     InstallLinuxPackageProgressStatus status,
     int progress_percent,
     const std::string& error_message) {
@@ -134,7 +134,7 @@
 }
 
 void AnsibleManagementService::GetAnsiblePlaybookToApply(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   DCHECK_GT(configuration_tasks_.count(container_id), 0);
   const base::FilePath& ansible_playbook_file_path =
       configuration_tasks_[container_id]->path;
@@ -151,7 +151,7 @@
 }
 
 void AnsibleManagementService::OnAnsiblePlaybookRetrieved(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool success) {
   if (!success) {
     LOG(ERROR) << "Failed to retrieve Ansible playbook content";
@@ -163,7 +163,7 @@
 }
 
 void AnsibleManagementService::ApplyAnsiblePlaybook(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   DCHECK_GT(configuration_tasks_.count(container_id), 0);
   if (!GetCiceroneClient()->IsApplyAnsiblePlaybookProgressSignalConnected()) {
     // Technically we could still start the application, but we wouldn't be able
@@ -187,7 +187,7 @@
 }
 
 void AnsibleManagementService::OnApplyAnsiblePlaybook(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     absl::optional<vm_tools::cicerone::ApplyAnsiblePlaybookResponse> response) {
   if (!response) {
     LOG(ERROR) << "Failed to apply Ansible playbook. Empty response.";
@@ -213,7 +213,7 @@
 
 void AnsibleManagementService::OnApplyAnsiblePlaybookProgress(
     const vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal& signal) {
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   switch (signal.status()) {
     case vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::SUCCEEDED:
       OnConfigurationFinished(container_id, true);
@@ -241,14 +241,14 @@
 }
 
 void AnsibleManagementService::OnUninstallPackageProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     UninstallPackageProgressStatus status,
     int progress_percent) {
   NOTIMPLEMENTED();
 }
 
 void AnsibleManagementService::OnConfigurationFinished(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool success) {
   DCHECK_GT(configuration_tasks_.count(container_id), 0);
   if (success && container_id == DefaultContainerId()) {
diff --git a/chrome/browser/ash/crostini/ansible/ansible_management_service.h b/chrome/browser/ash/crostini/ansible/ansible_management_service.h
index 6f2fd274..b05400e 100644
--- a/chrome/browser/ash/crostini/ansible/ansible_management_service.h
+++ b/chrome/browser/ash/crostini/ansible/ansible_management_service.h
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 class Profile;
@@ -41,12 +42,14 @@
    public:
     ~Observer() override = default;
     virtual void OnAnsibleSoftwareConfigurationStarted(
-        const ContainerId& container_id) = 0;
+        const guest_os::GuestId& container_id) = 0;
     virtual void OnAnsibleSoftwareConfigurationFinished(
-        const ContainerId& container_id,
+        const guest_os::GuestId& container_id,
         bool success) = 0;
-    virtual void OnAnsibleSoftwareInstall(const ContainerId& container_id) {}
-    virtual void OnApplyAnsiblePlaybook(const ContainerId& container_id) {}
+    virtual void OnAnsibleSoftwareInstall(
+        const guest_os::GuestId& container_id) {}
+    virtual void OnApplyAnsiblePlaybook(const guest_os::GuestId& container_id) {
+    }
   };
 
   static AnsibleManagementService* GetForProfile(Profile* profile);
@@ -59,16 +62,16 @@
   ~AnsibleManagementService() override;
 
   // Preconfigures a container with a specified Ansible playbook.
-  void ConfigureContainer(const ContainerId& container_id,
+  void ConfigureContainer(const guest_os::GuestId& container_id,
                           base::FilePath playbook,
                           base::OnceCallback<void(bool success)> callback);
 
   // LinuxPackageOperationProgressObserver:
-  void OnInstallLinuxPackageProgress(const ContainerId& container_id,
+  void OnInstallLinuxPackageProgress(const guest_os::GuestId& container_id,
                                      InstallLinuxPackageProgressStatus status,
                                      int progress_percent,
                                      const std::string& error_message) override;
-  void OnUninstallPackageProgress(const ContainerId& container_id,
+  void OnUninstallPackageProgress(const guest_os::GuestId& container_id,
                                   UninstallPackageProgressStatus status,
                                   int progress_percent) override;
 
@@ -79,23 +82,24 @@
   void RemoveObserver(Observer* observer);
 
  private:
-  void OnInstallAnsibleInContainer(const ContainerId& container_id,
+  void OnInstallAnsibleInContainer(const guest_os::GuestId& container_id,
                                    CrostiniResult result);
-  void GetAnsiblePlaybookToApply(const ContainerId& container_id);
-  void OnAnsiblePlaybookRetrieved(const ContainerId& container_id,
+  void GetAnsiblePlaybookToApply(const guest_os::GuestId& container_id);
+  void OnAnsiblePlaybookRetrieved(const guest_os::GuestId& container_id,
                                   bool success);
-  void ApplyAnsiblePlaybook(const ContainerId& container_id);
+  void ApplyAnsiblePlaybook(const guest_os::GuestId& container_id);
   void OnApplyAnsiblePlaybook(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       absl::optional<vm_tools::cicerone::ApplyAnsiblePlaybookResponse>
           response);
 
   // Helper function that runs relevant callback and notifies observers.
-  void OnConfigurationFinished(const ContainerId& container_id, bool success);
+  void OnConfigurationFinished(const guest_os::GuestId& container_id,
+                               bool success);
 
   Profile* profile_;
   base::ObserverList<Observer> observers_;
-  std::map<ContainerId, std::unique_ptr<AnsibleConfiguration>>
+  std::map<guest_os::GuestId, std::unique_ptr<AnsibleConfiguration>>
       configuration_tasks_;
 
   base::WeakPtrFactory<AnsibleManagementService> weak_ptr_factory_;
diff --git a/chrome/browser/ash/crostini/ansible/ansible_management_service_unittest.cc b/chrome/browser/ash/crostini/ansible/ansible_management_service_unittest.cc
index 3b7211e..e107120 100644
--- a/chrome/browser/ash/crostini/ansible/ansible_management_service_unittest.cc
+++ b/chrome/browser/ash/crostini/ansible/ansible_management_service_unittest.cc
@@ -94,17 +94,19 @@
 
   // AnsibleManagementService::Observer
   void OnAnsibleSoftwareConfigurationStarted(
-      const ContainerId& container_id) override {}
-  void OnAnsibleSoftwareConfigurationFinished(const ContainerId& container_id,
-                                              bool success) override {}
-  void OnAnsibleSoftwareInstall(const ContainerId& container_id) override {
+      const guest_os::GuestId& container_id) override {}
+  void OnAnsibleSoftwareConfigurationFinished(
+      const guest_os::GuestId& container_id,
+      bool success) override {}
+  void OnAnsibleSoftwareInstall(
+      const guest_os::GuestId& container_id) override {
     if (is_install_ansible_success_) {
       test_helper_->SendSucceededInstallSignal();
     } else {
       test_helper_->SendFailedInstallSignal();
     }
   }
-  void OnApplyAnsiblePlaybook(const ContainerId& container_id) override {
+  void OnApplyAnsiblePlaybook(const guest_os::GuestId& container_id) override {
     if (is_apply_ansible_success_) {
       test_helper_->SendSucceededApplySignal();
     } else {
diff --git a/chrome/browser/ash/crostini/crostini_disk.cc b/chrome/browser/ash/crostini/crostini_disk.cc
index 3b31892..59a064d37 100644
--- a/chrome/browser/ash/crostini/crostini_disk.cc
+++ b/chrome/browser/ash/crostini/crostini_disk.cc
@@ -94,7 +94,8 @@
     std::move(callback).Run(nullptr);
   } else {
     VLOG(1) << "Starting vm " << vm_name;
-    auto container_id = ContainerId(vm_name, kCrostiniDefaultContainerName);
+    auto container_id =
+        guest_os::GuestId(vm_name, kCrostiniDefaultContainerName);
     CrostiniManager::RestartOptions options;
     options.start_vm_only = true;
     CrostiniManager::GetForProfile(profile)->RestartCrostiniWithOptions(
@@ -265,7 +266,7 @@
                         std::string vm_name,
                         uint64_t size_bytes,
                         base::OnceCallback<void(bool)> callback) {
-  ContainerId container_id(vm_name, kCrostiniDefaultContainerName);
+  guest_os::GuestId container_id(vm_name, kCrostiniDefaultContainerName);
   CrostiniManager::RestartOptions options;
   options.start_vm_only = true;
   CrostiniManager::GetForProfile(profile)->RestartCrostiniWithOptions(
diff --git a/chrome/browser/ash/crostini/crostini_export_import.cc b/chrome/browser/ash/crostini/crostini_export_import.cc
index 90284cac..7ea83b5 100644
--- a/chrome/browser/ash/crostini/crostini_export_import.cc
+++ b/chrome/browser/ash/crostini/crostini_export_import.cc
@@ -90,7 +90,7 @@
 
 CrostiniExportImport::OperationData::OperationData(
     ExportImportType type,
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     OnceTrackerFactory tracker_factory)
     : type(type),
       container_id(std::move(container_id)),
@@ -100,7 +100,7 @@
 
 CrostiniExportImport::OperationData* CrostiniExportImport::NewOperationData(
     ExportImportType type,
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     OnceTrackerFactory factory) {
   auto operation_data = std::make_unique<OperationData>(
       type, std::move(container_id), std::move(factory));
@@ -112,9 +112,9 @@
 
 CrostiniExportImport::OperationData* CrostiniExportImport::NewOperationData(
     ExportImportType type,
-    ContainerId container_id) {
+    guest_os::GuestId container_id) {
   OnceTrackerFactory factory = base::BindOnce(
-      [](Profile* profile, ContainerId container_id,
+      [](Profile* profile, guest_os::GuestId container_id,
          std::string notification_id, ExportImportType type,
          base::FilePath path)
           -> std::unique_ptr<CrostiniExportImportStatusTracker> {
@@ -131,21 +131,21 @@
   return NewOperationData(type, DefaultContainerId());
 }
 
-void CrostiniExportImport::ExportContainer(ContainerId container_id,
+void CrostiniExportImport::ExportContainer(guest_os::GuestId container_id,
                                            content::WebContents* web_contents) {
   OpenFileDialog(
       NewOperationData(ExportImportType::EXPORT, std::move(container_id)),
       web_contents);
 }
 
-void CrostiniExportImport::ImportContainer(ContainerId container_id,
+void CrostiniExportImport::ImportContainer(guest_os::GuestId container_id,
                                            content::WebContents* web_contents) {
   OpenFileDialog(
       NewOperationData(ExportImportType::IMPORT, std::move(container_id)),
       web_contents);
 }
 
-void CrostiniExportImport::ExportContainer(ContainerId container_id,
+void CrostiniExportImport::ExportContainer(guest_os::GuestId container_id,
                                            content::WebContents* web_contents,
                                            OnceTrackerFactory tracker_factory) {
   OpenFileDialog(
@@ -154,7 +154,7 @@
       web_contents);
 }
 
-void CrostiniExportImport::ImportContainer(ContainerId container_id,
+void CrostiniExportImport::ImportContainer(guest_os::GuestId container_id,
                                            content::WebContents* web_contents,
                                            OnceTrackerFactory tracker_factory) {
   OpenFileDialog(
@@ -230,7 +230,7 @@
 }
 
 void CrostiniExportImport::ExportContainer(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     base::FilePath path,
     CrostiniManager::CrostiniResultCallback callback) {
   Start(NewOperationData(ExportImportType::EXPORT, std::move(container_id)),
@@ -238,14 +238,14 @@
 }
 
 void CrostiniExportImport::ImportContainer(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     base::FilePath path,
     CrostiniManager::CrostiniResultCallback callback) {
   Start(NewOperationData(ExportImportType::IMPORT, std::move(container_id)),
         path, std::move(callback));
 }
 
-void CrostiniExportImport::ExportContainer(ContainerId container_id,
+void CrostiniExportImport::ExportContainer(guest_os::GuestId container_id,
                                            base::FilePath path,
                                            OnceTrackerFactory tracker_factory) {
   Start(NewOperationData(ExportImportType::EXPORT, std::move(container_id),
@@ -253,7 +253,7 @@
         path, base::DoNothing());
 }
 
-void CrostiniExportImport::ImportContainer(ContainerId container_id,
+void CrostiniExportImport::ImportContainer(guest_os::GuestId container_id,
                                            base::FilePath path,
                                            OnceTrackerFactory tracker_factory) {
   Start(NewOperationData(ExportImportType::IMPORT, std::move(container_id),
@@ -326,7 +326,7 @@
 }
 
 void CrostiniExportImport::EnsureLxdStartedThenSharePath(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const base::FilePath& path,
     bool persist,
     guest_os::GuestOsSharePath::SharePathCallback callback) {
@@ -356,7 +356,7 @@
 }
 
 void CrostiniExportImport::ExportAfterSharing(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const base::FilePath& path,
     CrostiniManager::CrostiniResultCallback callback,
     const base::FilePath& container_path,
@@ -383,7 +383,7 @@
 
 void CrostiniExportImport::OnExportComplete(
     const base::Time& start,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniManager::CrostiniResultCallback callback,
     CrostiniResult result,
     uint64_t container_size,
@@ -471,7 +471,7 @@
 }
 
 void CrostiniExportImport::OnExportContainerProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const StreamingExportStatus& status) {
   auto it = status_trackers_.find(container_id);
   if (it == status_trackers_.end()) {
@@ -492,7 +492,7 @@
 }
 
 void CrostiniExportImport::ImportAfterSharing(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const base::FilePath& path,
     CrostiniManager::CrostiniResultCallback callback,
     const base::FilePath& container_path,
@@ -519,7 +519,7 @@
 
 void CrostiniExportImport::OnImportComplete(
     const base::Time& start,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniManager::CrostiniResultCallback callback,
     CrostiniResult result) {
   auto it = status_trackers_.find(container_id);
@@ -606,7 +606,7 @@
 }
 
 void CrostiniExportImport::OnImportContainerProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     ImportContainerProgressStatus status,
     int progress_percent,
     uint64_t progress_speed,
@@ -663,7 +663,7 @@
 }
 
 void CrostiniExportImport::CancelOperation(ExportImportType type,
-                                           ContainerId container_id) {
+                                           guest_os::GuestId container_id) {
   auto it = status_trackers_.find(container_id);
   if (it == status_trackers_.end()) {
     NOTREACHED() << container_id << " has no status_tracker to cancel";
@@ -692,7 +692,7 @@
 
 base::WeakPtr<CrostiniExportImportNotificationController>
 CrostiniExportImport::GetNotificationControllerForTesting(
-    ContainerId container_id) {
+    guest_os::GuestId container_id) {
   auto it = status_trackers_.find(container_id);
   if (it == status_trackers_.end()) {
     return nullptr;
diff --git a/chrome/browser/ash/crostini/crostini_export_import.h b/chrome/browser/ash/crostini/crostini_export_import.h
index 24d9f69..9a0d74f 100644
--- a/chrome/browser/ash/crostini/crostini_export_import.h
+++ b/chrome/browser/ash/crostini/crostini_export_import.h
@@ -16,6 +16,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/crostini/crostini_export_import_notification_controller.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/guest_os_share_path.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
@@ -79,12 +80,12 @@
 
   struct OperationData {
     OperationData(ExportImportType type,
-                  ContainerId id,
+                  guest_os::GuestId id,
                   OnceTrackerFactory factory);
     ~OperationData();
 
     ExportImportType type;
-    ContainerId container_id;
+    guest_os::GuestId container_id;
     OnceTrackerFactory tracker_factory;
   };
 
@@ -107,45 +108,45 @@
   void Shutdown() override;
 
   // Export the |container_id| showing FileDialog.
-  void ExportContainer(ContainerId container_id,
+  void ExportContainer(guest_os::GuestId container_id,
                        content::WebContents* web_contents);
   // Import the |container_id| showing FileDialog.
-  void ImportContainer(ContainerId container_id,
+  void ImportContainer(guest_os::GuestId container_id,
                        content::WebContents* web_contents);
 
   // Export |container_id| to |path| and invoke |callback| when complete.
-  void ExportContainer(ContainerId container_id,
+  void ExportContainer(guest_os::GuestId container_id,
                        base::FilePath path,
                        CrostiniManager::CrostiniResultCallback callback);
   // Import |container_id| from |path| and invoke |callback| when complete.
-  void ImportContainer(ContainerId container_id,
+  void ImportContainer(guest_os::GuestId container_id,
                        base::FilePath path,
                        CrostiniManager::CrostiniResultCallback callback);
 
   // Export |container_id| showing FileDialog, and using |tracker_factory| for
   // status tracking.
-  void ExportContainer(ContainerId container_id,
+  void ExportContainer(guest_os::GuestId container_id,
                        content::WebContents* web_contents,
                        OnceTrackerFactory tracker_factory);
   // Import |container_id| showing FileDialog, and using |tracker_factory| for
   // status tracking.
-  void ImportContainer(ContainerId container_id,
+  void ImportContainer(guest_os::GuestId container_id,
                        content::WebContents* web_contents,
                        OnceTrackerFactory tracker_factory);
 
   // Export |container| to |path| and invoke |tracker_factory| to create a
   // tracker for this operation.
-  void ExportContainer(ContainerId container_id,
+  void ExportContainer(guest_os::GuestId container_id,
                        base::FilePath path,
                        OnceTrackerFactory tracker_factory);
   // Import |container| from |path| and invoke |tracker_factory| to create a
   // tracker for this operation.
-  void ImportContainer(ContainerId container_id,
+  void ImportContainer(guest_os::GuestId container_id,
                        base::FilePath path,
                        OnceTrackerFactory tracker_factory);
 
   // Cancel currently running export/import.
-  void CancelOperation(ExportImportType type, ContainerId id);
+  void CancelOperation(ExportImportType type, guest_os::GuestId id);
 
   // Whether an export or import is currently in progress.
   bool GetExportImportOperationStatus() const;
@@ -154,7 +155,7 @@
   base::FilePath GetDefaultBackupPath() const;
 
   base::WeakPtr<CrostiniExportImportNotificationController>
-  GetNotificationControllerForTesting(ContainerId container_id);
+  GetNotificationControllerForTesting(guest_os::GuestId container_id);
 
  private:
   FRIEND_TEST_ALL_PREFIXES(CrostiniExportImportTest,
@@ -178,9 +179,9 @@
   FRIEND_TEST_ALL_PREFIXES(CrostiniExportImportTest, TestImportFailSpace);
 
   OperationData* NewOperationData(ExportImportType type,
-                                  ContainerId id,
+                                  guest_os::GuestId id,
                                   OnceTrackerFactory cb);
-  OperationData* NewOperationData(ExportImportType type, ContainerId id);
+  OperationData* NewOperationData(ExportImportType type, guest_os::GuestId id);
   OperationData* NewOperationData(ExportImportType type);
 
   // ui::SelectFileDialog::Listener implementation.
@@ -195,7 +196,7 @@
 
   // Restart VM with LXD if required and share the file path with VM.
   void EnsureLxdStartedThenSharePath(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       const base::FilePath& path,
       bool persist,
       guest_os::GuestOsSharePath::SharePathCallback callback);
@@ -207,11 +208,11 @@
                  crostini::CrostiniResult result);
 
   // crostini::ExportContainerProgressObserver implementation.
-  void OnExportContainerProgress(const ContainerId& container_id,
+  void OnExportContainerProgress(const guest_os::GuestId& container_id,
                                  const StreamingExportStatus& status) override;
 
   // crostini::ImportContainerProgressObserver implementation.
-  void OnImportContainerProgress(const ContainerId& container_id,
+  void OnImportContainerProgress(const guest_os::GuestId& container_id,
                                  crostini::ImportContainerProgressStatus status,
                                  int progress_percent,
                                  uint64_t progress_speed,
@@ -220,27 +221,27 @@
                                  uint64_t available_space,
                                  uint64_t minimum_required_space) override;
 
-  void ExportAfterSharing(const ContainerId& container_id,
+  void ExportAfterSharing(const guest_os::GuestId& container_id,
                           const base::FilePath& path,
                           CrostiniManager::CrostiniResultCallback callback,
                           const base::FilePath& container_path,
                           bool result,
                           const std::string& failure_reason);
   void OnExportComplete(const base::Time& start,
-                        const ContainerId& container_id,
+                        const guest_os::GuestId& container_id,
                         CrostiniManager::CrostiniResultCallback callback,
                         CrostiniResult result,
                         uint64_t container_size,
                         uint64_t compressed_size);
 
-  void ImportAfterSharing(const ContainerId& container_id,
+  void ImportAfterSharing(const guest_os::GuestId& container_id,
                           const base::FilePath& path,
                           CrostiniManager::CrostiniResultCallback callback,
                           const base::FilePath& container_path,
                           bool result,
                           const std::string& failure_reason);
   void OnImportComplete(const base::Time& start,
-                        const ContainerId& container_id,
+                        const guest_os::GuestId& container_id,
                         CrostiniManager::CrostiniResultCallback callback,
                         CrostiniResult result);
 
@@ -250,7 +251,8 @@
   std::string GetUniqueNotificationId();
 
   using TrackerMap =
-      std::map<ContainerId, std::unique_ptr<CrostiniExportImportStatusTracker>>;
+      std::map<guest_os::GuestId,
+               std::unique_ptr<CrostiniExportImportStatusTracker>>;
 
   std::unique_ptr<CrostiniExportImportStatusTracker> RemoveTracker(
       TrackerMap::iterator it);
diff --git a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc
index 3188035..4b8dd83 100644
--- a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc
+++ b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.cc
@@ -48,7 +48,7 @@
         ExportImportType type,
         const std::string& notification_id,
         base::FilePath path,
-        ContainerId container_id)
+        guest_os::GuestId container_id)
     : CrostiniExportImportStatusTracker(type, std::move(path)),
       profile_(profile),
       container_id_(std::move(container_id)),
@@ -94,8 +94,8 @@
   }
 
   delegate_->SetCallback(base::BindRepeating(
-      [](Profile* profile, ExportImportType type, ContainerId container_id,
-         absl::optional<int> button_index) {
+      [](Profile* profile, ExportImportType type,
+         guest_os::GuestId container_id, absl::optional<int> button_index) {
         if (!button_index.has_value()) {
           return;
         }
diff --git a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.h b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.h
index 01f5cfc..ad9a9e8 100644
--- a/chrome/browser/ash/crostini/crostini_export_import_notification_controller.h
+++ b/chrome/browser/ash/crostini/crostini_export_import_notification_controller.h
@@ -55,7 +55,7 @@
                                              ExportImportType type,
                                              const std::string& notification_id,
                                              base::FilePath path,
-                                             ContainerId container_id);
+                                             guest_os::GuestId container_id);
 
   CrostiniExportImportNotificationController(
       const CrostiniExportImportNotificationController&) = delete;
@@ -88,7 +88,7 @@
   void on_notification_closed() { hidden_ = true; }
 
   Profile* profile_;  // Not owned.
-  ContainerId container_id_;
+  guest_os::GuestId container_id_;
   // |delegate_| is responsible for handling click events. It is separate from
   // the controller because it needs to live as long as the notification is in
   // the UI, but the controller's lifetime ends once the notification is in a
diff --git a/chrome/browser/ash/crostini/crostini_export_import_unittest.cc b/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
index 5d363fd..ad53c4c 100644
--- a/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
@@ -46,13 +46,13 @@
 class CrostiniExportImportTest : public testing::Test {
  public:
   base::WeakPtr<CrostiniExportImportNotificationController> GetController(
-      const ContainerId& container_id) {
+      const guest_os::GuestId& container_id) {
     return crostini_export_import_->GetNotificationControllerForTesting(
         container_id);
   }
 
   const message_center::Notification& GetNotification(
-      const ContainerId& container_id) {
+      const guest_os::GuestId& container_id) {
     // Assertions in this function are wrap in IILEs because you cannot assert
     // in a function with a non-void return type.
     const base::WeakPtr<CrostiniExportImportNotificationController>&
@@ -89,7 +89,7 @@
   }
 
   void SendExportProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       vm_tools::cicerone::ExportLxdContainerProgressSignal_Status status,
       const ExportProgressOptionalArguments& arguments = {}) {
     vm_tools::cicerone::ExportLxdContainerProgressSignal signal;
@@ -105,7 +105,7 @@
   }
 
   void SendImportProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       vm_tools::cicerone::ImportLxdContainerProgressSignal_Status status,
       const ImportProgressOptionalArguments& arguments = {}) {
     vm_tools::cicerone::ImportLxdContainerProgressSignal signal;
@@ -196,8 +196,8 @@
       notification_display_service_tester_;
   StubNotificationDisplayService* notification_display_service_;
 
-  ContainerId default_container_id_;
-  ContainerId custom_container_id_;
+  guest_os::GuestId default_container_id_;
+  guest_os::GuestId custom_container_id_;
   base::FilePath tarball_;
 
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/ash/crostini/crostini_installer.cc b/chrome/browser/ash/crostini/crostini_installer.cc
index cc575f6..5224430b 100644
--- a/chrome/browser/ash/crostini/crostini_installer.cc
+++ b/chrome/browser/ash/crostini/crostini_installer.cc
@@ -402,14 +402,14 @@
 // configurations currently work as configure on every startup, we'll have a
 // potential overlap which will cause this to signal too many times.
 void CrostiniInstaller::OnAnsibleSoftwareConfigurationStarted(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   DCHECK_EQ(installing_state_, InstallerState::kStartContainer);
   UpdateInstallingState(InstallerState::kConfigureContainer);
 }
 
 // TODO(justinhuang): Similar to the above.
 void CrostiniInstaller::OnAnsibleSoftwareConfigurationFinished(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool success) {
   DCHECK_EQ(installing_state_, InstallerState::kConfigureContainer);
   DCHECK(ansible_management_service_observation_.IsObservingSource(
diff --git a/chrome/browser/ash/crostini/crostini_installer.h b/chrome/browser/ash/crostini/crostini_installer.h
index ba354b9fa..4f54e38 100644
--- a/chrome/browser/ash/crostini/crostini_installer.h
+++ b/chrome/browser/ash/crostini/crostini_installer.h
@@ -106,9 +106,10 @@
 
   // AnsibleManagementService::Observer:
   void OnAnsibleSoftwareConfigurationStarted(
-      const ContainerId& container_id) override;
-  void OnAnsibleSoftwareConfigurationFinished(const ContainerId& container_id,
-                                              bool success) override;
+      const guest_os::GuestId& container_id) override;
+  void OnAnsibleSoftwareConfigurationFinished(
+      const guest_os::GuestId& container_id,
+      bool success) override;
 
   // Return true if internal state allows starting installation.
   bool CanInstall();
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index a34a8ea..a85028b 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -84,7 +84,7 @@
 // |arguments|... and erase them from the map.
 template <typename... Parameters, typename... Arguments>
 void InvokeAndErasePendingCallbacks(
-    std::map<ContainerId, base::OnceCallback<void(Parameters...)>>*
+    std::map<guest_os::GuestId, base::OnceCallback<void(Parameters...)>>*
         vm_keyed_map,
     const std::string& vm_name,
     Arguments&&... arguments) {
@@ -119,9 +119,9 @@
 // Find any container callbacks for the specified |container_id|, invoke them
 // with |result| and erase them from the map.
 void InvokeAndErasePendingContainerCallbacks(
-    std::multimap<ContainerId, CrostiniManager::CrostiniResultCallback>*
+    std::multimap<guest_os::GuestId, CrostiniManager::CrostiniResultCallback>*
         container_callbacks,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResult result) {
   auto range = container_callbacks->equal_range(container_id);
   for (auto it = range.first; it != range.second; ++it) {
@@ -197,7 +197,7 @@
 
   CrostiniRestarter(Profile* profile,
                     CrostiniManager* crostini_manager,
-                    ContainerId container_id,
+                    guest_os::GuestId container_id,
                     RestartRequest request);
   ~CrostiniRestarter() override;
 
@@ -227,7 +227,7 @@
   void OnLxdContainerStarting(
       vm_tools::cicerone::LxdContainerStartingSignal_Status status);
 
-  const ContainerId& container_id() { return container_id_; }
+  const guest_os::GuestId& container_id() { return container_id_; }
 
   // This is public so CallRestarterStartLxdContainerFinishedForTesting can call
   // it.
@@ -313,7 +313,7 @@
   // reference to it during the CrostiniRestarter destructor.
   CrostiniManager* crostini_manager_;
 
-  const ContainerId container_id_;
+  const guest_os::GuestId container_id_;
   bool is_initial_install_ = false;
   std::vector<base::OnceClosure> abort_callbacks_;
   // Options which only affect new containers will be taken from the first
@@ -337,7 +337,7 @@
 CrostiniManager::CrostiniRestarter::CrostiniRestarter(
     Profile* profile,
     CrostiniManager* crostini_manager,
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     RestartRequest request)
     : profile_(profile),
       crostini_manager_(crostini_manager),
@@ -1056,7 +1056,7 @@
 }  // namespace
 
 void CrostiniManager::SetContainerOsRelease(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const vm_tools::cicerone::OsRelease& os_release) {
   ContainerOsVersion version = VersionFromOsRelease(os_release);
   // Store the os release version in prefs. We can use this value to decide if
@@ -1134,7 +1134,7 @@
 }
 
 const vm_tools::cicerone::OsRelease* CrostiniManager::GetContainerOsRelease(
-    const ContainerId& container_id) const {
+    const guest_os::GuestId& container_id) const {
   auto it = container_os_releases_.find(container_id);
   if (it != container_os_releases_.end()) {
     return &it->second;
@@ -1143,7 +1143,7 @@
 }
 
 bool CrostiniManager::IsContainerUpgradeable(
-    const ContainerId& container_id) const {
+    const guest_os::GuestId& container_id) const {
   ContainerOsVersion version = ContainerOsVersion::kUnknown;
   const auto* os_release = GetContainerOsRelease(container_id);
   if (os_release) {
@@ -1160,7 +1160,7 @@
 }
 
 bool CrostiniManager::ShouldPromptContainerUpgrade(
-    const ContainerId& container_id) const {
+    const guest_os::GuestId& container_id) const {
   if (!CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(profile_)) {
     return false;
   }
@@ -1175,7 +1175,8 @@
   return upgradable;
 }
 
-void CrostiniManager::UpgradePromptShown(const ContainerId& container_id) {
+void CrostiniManager::UpgradePromptShown(
+    const guest_os::GuestId& container_id) {
   container_upgrade_prompt_shown_.insert(container_id);
 }
 
@@ -1188,7 +1189,7 @@
 }
 
 absl::optional<ContainerInfo> CrostiniManager::GetContainerInfo(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   if (!IsVmRunning(container_id.vm_name)) {
     return absl::nullopt;
   }
@@ -1602,7 +1603,7 @@
 }  // namespace
 
 void CrostiniManager::CreateLxdContainer(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     absl::optional<std::string> opt_image_server_url,
     absl::optional<std::string> opt_image_alias,
     CrostiniResultCallback callback) {
@@ -1641,7 +1642,7 @@
                      std::move(callback)));
 }
 
-void CrostiniManager::DeleteLxdContainer(ContainerId container_id,
+void CrostiniManager::DeleteLxdContainer(guest_os::GuestId container_id,
                                          BoolCallback callback) {
   if (container_id.vm_name.empty()) {
     LOG(ERROR) << "vm_name is required";
@@ -1673,7 +1674,7 @@
 }
 
 void CrostiniManager::OnDeleteLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     BoolCallback callback,
     absl::optional<vm_tools::cicerone::DeleteLxdContainerResponse> response) {
   if (!response) {
@@ -1699,7 +1700,7 @@
   }
 }
 
-void CrostiniManager::StartLxdContainer(ContainerId container_id,
+void CrostiniManager::StartLxdContainer(guest_os::GuestId container_id,
                                         CrostiniResultCallback callback) {
   if (container_id.vm_name.empty()) {
     LOG(ERROR) << "vm_name is required";
@@ -1735,7 +1736,7 @@
                      std::move(callback)));
 }
 
-void CrostiniManager::StopLxdContainer(ContainerId container_id,
+void CrostiniManager::StopLxdContainer(guest_os::GuestId container_id,
                                        CrostiniResultCallback callback) {
   if (container_id.vm_name.empty()) {
     LOG(ERROR) << "vm_name is required";
@@ -1758,7 +1759,7 @@
                      std::move(callback)));
 }
 
-void CrostiniManager::SetUpLxdContainerUser(ContainerId container_id,
+void CrostiniManager::SetUpLxdContainerUser(guest_os::GuestId container_id,
                                             std::string container_username,
                                             BoolCallback callback) {
   if (container_id.vm_name.empty()) {
@@ -1789,7 +1790,7 @@
 }
 
 void CrostiniManager::ExportLxdContainer(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     base::FilePath export_path,
     ExportLxdContainerResultCallback callback) {
   if (container_id.vm_name.empty()) {
@@ -1828,7 +1829,7 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(container_id)));
 }
 
-void CrostiniManager::ImportLxdContainer(ContainerId container_id,
+void CrostiniManager::ImportLxdContainer(guest_os::GuestId container_id,
                                          base::FilePath import_path,
                                          CrostiniResultCallback callback) {
   if (container_id.vm_name.empty()) {
@@ -1865,7 +1866,7 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(container_id)));
 }
 
-void CrostiniManager::CancelExportLxdContainer(ContainerId key) {
+void CrostiniManager::CancelExportLxdContainer(guest_os::GuestId key) {
   const auto& vm_name = key.vm_name;
   const auto& container_name = key.container_name;
   if (vm_name.empty()) {
@@ -1893,7 +1894,7 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(key)));
 }
 
-void CrostiniManager::CancelImportLxdContainer(ContainerId key) {
+void CrostiniManager::CancelImportLxdContainer(guest_os::GuestId key) {
   const auto& vm_name = key.vm_name;
   const auto& container_name = key.container_name;
   if (vm_name.empty()) {
@@ -1939,7 +1940,7 @@
 
 }  // namespace
 
-void CrostiniManager::UpgradeContainer(const ContainerId& key,
+void CrostiniManager::UpgradeContainer(const guest_os::GuestId& key,
                                        ContainerVersion target_version,
                                        CrostiniResultCallback callback) {
   const auto& vm_name = key.vm_name;
@@ -1996,7 +1997,7 @@
   }
 }
 
-void CrostiniManager::CancelUpgradeContainer(const ContainerId& key,
+void CrostiniManager::CancelUpgradeContainer(const guest_os::GuestId& key,
                                              CrostiniResultCallback callback) {
   const auto& vm_name = key.vm_name;
   const auto& container_name = key.container_name;
@@ -2021,7 +2022,7 @@
 }
 
 void CrostiniManager::LaunchContainerApplication(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::string desktop_file_id,
     const std::vector<std::string>& files,
     bool display_scaled,
@@ -2046,7 +2047,7 @@
 }
 
 void CrostiniManager::GetContainerAppIcons(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::vector<std::string> desktop_file_ids,
     int icon_size,
     int scale,
@@ -2069,7 +2070,7 @@
 }
 
 void CrostiniManager::GetLinuxPackageInfo(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::string package_path,
     GetLinuxPackageInfoCallback callback) {
   vm_tools::cicerone::LinuxPackageInfoRequest request;
@@ -2085,7 +2086,7 @@
 }
 
 void CrostiniManager::InstallLinuxPackage(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::string package_path,
     InstallLinuxPackageCallback callback) {
   if (!CrostiniFeatures::Get()->IsRootAccessAllowed(profile_)) {
@@ -2117,7 +2118,7 @@
 }
 
 void CrostiniManager::InstallLinuxPackageFromApt(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::string package_id,
     InstallLinuxPackageCallback callback) {
   if (!GetCiceroneClient()->IsInstallLinuxPackageProgressSignalConnected()) {
@@ -2142,7 +2143,7 @@
 }
 
 void CrostiniManager::UninstallPackageOwningFile(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     std::string desktop_file_id,
     CrostiniResultCallback callback) {
   if (!GetCiceroneClient()->IsUninstallPackageProgressSignalConnected()) {
@@ -2167,7 +2168,7 @@
 }
 
 void CrostiniManager::GetContainerSshKeys(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     GetContainerSshKeysCallback callback) {
   vm_tools::concierge::ContainerSshKeysRequest request;
   request.set_vm_name(container_id.vm_name);
@@ -2236,7 +2237,7 @@
   container_shutdown_observers_.RemoveObserver(observer);
 }
 
-void CrostiniManager::AddFileWatch(const ContainerId& container_id,
+void CrostiniManager::AddFileWatch(const guest_os::GuestId& container_id,
                                    const base::FilePath& path,
                                    BoolCallback callback) {
   vm_tools::cicerone::AddFileWatchRequest request;
@@ -2258,7 +2259,7 @@
           std::move(callback)));
 }
 
-void CrostiniManager::RemoveFileWatch(const ContainerId& container_id,
+void CrostiniManager::RemoveFileWatch(const guest_os::GuestId& container_id,
                                       const base::FilePath& path) {
   vm_tools::cicerone::RemoveFileWatchRequest request;
   request.set_vm_name(container_id.vm_name);
@@ -2282,12 +2283,12 @@
     const vm_tools::cicerone::FileWatchTriggeredSignal& signal) {
   for (auto& observer : file_change_observers_) {
     observer.OnCrostiniFileChanged(
-        ContainerId(signal.vm_name(), signal.container_name()),
+        guest_os::GuestId(signal.vm_name(), signal.container_name()),
         base::FilePath(signal.path()));
   }
 }
 
-void CrostiniManager::GetVshSession(const ContainerId& container_id,
+void CrostiniManager::GetVshSession(const guest_os::GuestId& container_id,
                                     int32_t host_vsh_pid,
                                     VshSessionCallback callback) {
   vm_tools::cicerone::GetVshSessionRequest request;
@@ -2313,7 +2314,7 @@
 }
 
 CrostiniManager::RestartId CrostiniManager::RestartCrostini(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     CrostiniResultCallback callback,
     RestartObserver* observer) {
   return RestartCrostiniWithOptions(std::move(container_id), RestartOptions(),
@@ -2321,7 +2322,7 @@
 }
 
 CrostiniManager::RestartId CrostiniManager::RestartCrostiniWithOptions(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     RestartOptions options,
     CrostiniResultCallback callback,
     RestartObserver* observer) {
@@ -2391,7 +2392,7 @@
 }
 
 void CrostiniManager::AddShutdownContainerCallback(
-    ContainerId container_id,
+    guest_os::GuestId container_id,
     base::OnceClosure shutdown_callback) {
   shutdown_container_callbacks_.emplace(std::move(container_id),
                                         std::move(shutdown_callback));
@@ -2756,7 +2757,7 @@
     const vm_tools::cicerone::ContainerStartedSignal& signal) {
   if (signal.owner_id() != owner_id_)
     return;
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
 
   auto* engagement_metrics_service =
       CrostiniEngagementMetricsService::Factory::GetForProfile(profile_);
@@ -2777,9 +2778,10 @@
   if (signal.vm_name() == kCrostiniDefaultVmName) {
     AddShutdownContainerCallback(
         container_id,
-        base::BindOnce(&CrostiniManager::DeallocateForwardedPortsCallback,
-                       weak_ptr_factory_.GetWeakPtr(), std::move(profile_),
-                       ContainerId(signal.vm_name(), signal.container_name())));
+        base::BindOnce(
+            &CrostiniManager::DeallocateForwardedPortsCallback,
+            weak_ptr_factory_.GetWeakPtr(), std::move(profile_),
+            guest_os::GuestId(signal.vm_name(), signal.container_name())));
   }
   for (auto& observer : container_started_observers_) {
     observer.OnContainerStarted(container_id);
@@ -2810,7 +2812,7 @@
   if (signal.owner_id() != owner_id_)
     return;
 
-  ContainerId container(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container(signal.vm_name(), signal.container_name());
   LOG(ERROR) << "Container startup failed for container: " << container;
   InvokeAndErasePendingContainerCallbacks(
       &start_container_callbacks_, container,
@@ -2821,7 +2823,7 @@
     const vm_tools::cicerone::ContainerShutdownSignal& signal) {
   if (signal.owner_id() != owner_id_)
     return;
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   // Find the callbacks to call, then erase them from the map.
   auto range_callbacks =
       shutdown_container_callbacks_.equal_range(container_id);
@@ -2864,7 +2866,7 @@
       NOTREACHED();
   }
 
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   for (auto& observer : linux_package_operation_progress_observers_) {
     observer.OnInstallLinuxPackageProgress(
         container_id, status, signal.progress_percent(), error_message);
@@ -2898,7 +2900,7 @@
       NOTREACHED();
   }
 
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   for (auto& observer : linux_package_operation_progress_observers_) {
     observer.OnUninstallPackageProgress(container_id, status,
                                         signal.progress_percent());
@@ -2946,7 +2948,7 @@
     }
   }
 
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   for (auto& observer : upgrade_container_progress_observers_) {
     observer.OnUpgradeContainerProgress(container_id, status,
                                         progress_messages);
@@ -3011,7 +3013,7 @@
 }
 
 void CrostiniManager::OnCreateLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResultCallback callback,
     absl::optional<vm_tools::cicerone::CreateLxdContainerResponse> response) {
   if (!response) {
@@ -3044,7 +3046,7 @@
 }
 
 void CrostiniManager::OnStartLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResultCallback callback,
     absl::optional<vm_tools::cicerone::StartLxdContainerResponse> response) {
   if (!response) {
@@ -3092,7 +3094,7 @@
 }
 
 void CrostiniManager::OnStopLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResultCallback callback,
     absl::optional<vm_tools::cicerone::StopLxdContainerResponse> response) {
   if (!response) {
@@ -3131,7 +3133,7 @@
 }
 
 void CrostiniManager::OnSetUpLxdContainerUser(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     BoolCallback callback,
     absl::optional<vm_tools::cicerone::SetUpLxdContainerUserResponse>
         response) {
@@ -3192,7 +3194,7 @@
     const vm_tools::cicerone::LxdContainerCreatedSignal& signal) {
   if (signal.owner_id() != owner_id_)
     return;
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   CrostiniResult result;
 
   switch (signal.status()) {
@@ -3232,7 +3234,7 @@
   if (signal.owner_id() != owner_id_)
     return;
 
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   bool success =
       signal.status() == vm_tools::cicerone::LxdContainerDeletedSignal::DELETED;
   if (success) {
@@ -3256,7 +3258,7 @@
   if (owner_id_ != signal.owner_id()) {
     return;
   }
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   auto iter = restarters_by_container_.find(container_id);
   if (iter != restarters_by_container_.end()) {
     iter->second->OnContainerDownloading(signal.download_progress());
@@ -3289,7 +3291,7 @@
           << signal.status() << " for container " << signal.container_name();
   if (signal.owner_id() != owner_id_)
     return;
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   CrostiniResult result;
 
   switch (signal.status()) {
@@ -3352,7 +3354,7 @@
     const vm_tools::cicerone::LxdContainerStoppingSignal& signal) {
   if (signal.owner_id() != owner_id_)
     return;
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   CrostiniResult result;
   switch (signal.status()) {
     case vm_tools::cicerone::LxdContainerStoppingSignal::UNKNOWN:
@@ -3540,7 +3542,7 @@
 
 void CrostiniManager::RestartCompleted(CrostiniRestarter* restarter,
                                        base::OnceClosure closure) {
-  ContainerId container_id = restarter->container_id();
+  guest_os::GuestId container_id = restarter->container_id();
   restarter = nullptr;
   // Destroy the restarter.
   restarters_by_container_.erase(container_id);
@@ -3553,7 +3555,7 @@
 }
 
 void CrostiniManager::OnExportLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     absl::optional<vm_tools::cicerone::ExportLxdContainerResponse> response) {
   auto it = export_lxd_container_callbacks_.find(container_id);
   if (it == export_lxd_container_callbacks_.end()) {
@@ -3589,7 +3591,8 @@
   if (signal.owner_id() != owner_id_)
     return;
 
-  const ContainerId container_id(signal.vm_name(), signal.container_name());
+  const guest_os::GuestId container_id(signal.vm_name(),
+                                       signal.container_name());
 
   CrostiniResult result;
   switch (signal.status()) {
@@ -3628,7 +3631,7 @@
 }
 
 void CrostiniManager::OnImportLxdContainer(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     absl::optional<vm_tools::cicerone::ImportLxdContainerResponse> response) {
   auto it = import_lxd_container_callbacks_.find(container_id);
   if (it == import_lxd_container_callbacks_.end()) {
@@ -3700,7 +3703,8 @@
                  << ", " << signal.failure_reason();
   }
 
-  const ContainerId container_id(signal.vm_name(), signal.container_name());
+  const guest_os::GuestId container_id(signal.vm_name(),
+                                       signal.container_name());
 
   if (call_observers) {
     for (auto& observer : import_container_progress_observers_) {
@@ -3725,7 +3729,7 @@
 }
 
 void CrostiniManager::OnCancelExportLxdContainer(
-    const ContainerId& key,
+    const guest_os::GuestId& key,
     absl::optional<vm_tools::cicerone::CancelExportLxdContainerResponse>
         response) {
   auto it = export_lxd_container_callbacks_.find(key);
@@ -3748,7 +3752,7 @@
 }
 
 void CrostiniManager::OnCancelImportLxdContainer(
-    const ContainerId& key,
+    const guest_os::GuestId& key,
     absl::optional<vm_tools::cicerone::CancelImportLxdContainerResponse>
         response) {
   auto it = import_lxd_container_callbacks_.find(key);
@@ -3834,7 +3838,7 @@
 
 void CrostiniManager::OnPendingAppListUpdates(
     const vm_tools::cicerone::PendingAppListUpdatesSignal& signal) {
-  ContainerId container_id(signal.vm_name(), signal.container_name());
+  guest_os::GuestId container_id(signal.vm_name(), signal.container_name());
   for (auto& observer : pending_app_list_updates_observers_) {
     observer.OnPendingAppListUpdates(container_id, signal.count());
   }
@@ -3883,7 +3887,7 @@
 void CrostiniManager::SuspendDone(base::TimeDelta sleep_duration) {
   // https://crbug.com/968060.  Sshfs is unmounted before suspend,
   // call RestartCrostini to force remount if container is running.
-  ContainerId container_id = DefaultContainerId();
+  guest_os::GuestId container_id = DefaultContainerId();
   if (GetContainerInfo(container_id)) {
     // TODO(crbug/1142321): Double-check if anything breaks if we change this
     // to just remount the sshfs mounts, in particular check 9p mounts.
@@ -3909,7 +3913,7 @@
 
 void CrostiniManager::DeallocateForwardedPortsCallback(
     Profile* profile,
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   crostini::CrostiniPortForwarder::GetForProfile(profile)
       ->DeactivateAllActivePorts(container_id);
 }
@@ -3964,7 +3968,7 @@
       }));
 }
 
-void CrostiniManager::MountCrostiniFiles(ContainerId container_id,
+void CrostiniManager::MountCrostiniFiles(guest_os::GuestId container_id,
                                          CrostiniResultCallback callback,
                                          bool background) {
   crostini_sshfs_->MountCrostiniFiles(
@@ -4013,7 +4017,8 @@
   restarter_it->second->StartLxdContainerFinished(result);
 }
 
-void CrostiniManager::RemoveStoppedContainer(const ContainerId& container_id) {
+void CrostiniManager::RemoveStoppedContainer(
+    const guest_os::GuestId& container_id) {
   // Run all ContainerShutdown observers
   for (auto& observer : container_shutdown_observers_) {
     observer.OnContainerShutdown(container_id);
@@ -4036,7 +4041,7 @@
   }
 }
 
-void CrostiniManager::RegisterContainer(const ContainerId& container_id) {
+void CrostiniManager::RegisterContainer(const guest_os::GuestId& container_id) {
   if (terminal_provider_ids_.find(container_id) !=
       terminal_provider_ids_.end()) {
     // Already registered, do nothing.
@@ -4048,7 +4053,8 @@
       std::make_unique<CrostiniTerminalProvider>(container_id));
 }
 
-void CrostiniManager::UnregisterContainer(const ContainerId& container_id) {
+void CrostiniManager::UnregisterContainer(
+    const guest_os::GuestId& container_id) {
   auto* terminal_registry = guest_os::GuestOsService::GetForProfile(profile_)
                                 ->TerminalProviderRegistry();
   auto it = terminal_provider_ids_.find(container_id);
diff --git a/chrome/browser/ash/crostini/crostini_manager.h b/chrome/browser/ash/crostini/crostini_manager.h
index 737db14..87c404f0 100644
--- a/chrome/browser/ash/crostini/crostini_manager.h
+++ b/chrome/browser/ash/crostini/crostini_manager.h
@@ -21,6 +21,7 @@
 #include "chrome/browser/ash/crostini/crostini_types.mojom-forward.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/crostini/termina_installer.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_terminal_provider_registry.h"
 #include "chrome/browser/ash/vm_shutdown_observer.h"
 #include "chrome/browser/ash/vm_starting_observer.h"
@@ -57,14 +58,14 @@
   // DOWNLOADING or INSTALLING. If |status| is FAILED, the |error_message|
   // will contain output of the failing installation command.
   virtual void OnInstallLinuxPackageProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       InstallLinuxPackageProgressStatus status,
       int progress_percent,
       const std::string& error_message) = 0;
 
   // A successfully started package uninstall will continually fire progress
   // events until it returns a status of SUCCEEDED or FAILED.
-  virtual void OnUninstallPackageProgress(const ContainerId& container_id,
+  virtual void OnUninstallPackageProgress(const guest_os::GuestId& container_id,
                                           UninstallPackageProgressStatus status,
                                           int progress_percent) = 0;
 };
@@ -72,7 +73,7 @@
 class PendingAppListUpdatesObserver : public base::CheckedObserver {
  public:
   // Called whenever the kPendingAppListUpdatesMethod signal is sent.
-  virtual void OnPendingAppListUpdates(const ContainerId& container_id,
+  virtual void OnPendingAppListUpdates(const guest_os::GuestId& container_id,
                                        int count) = 0;
 };
 
@@ -81,7 +82,7 @@
   // A successfully started container export will continually fire progress
   // events until the original callback from ExportLxdContainer is invoked with
   // a status of SUCCESS or CONTAINER_EXPORT_FAILED.
-  virtual void OnExportContainerProgress(const ContainerId& container_id,
+  virtual void OnExportContainerProgress(const guest_os::GuestId& container_id,
                                          const StreamingExportStatus&) = 0;
 };
 
@@ -91,7 +92,7 @@
   // events until the original callback from ImportLxdContainer is invoked with
   // a status of SUCCESS or CONTAINER_IMPORT_FAILED[_*].
   virtual void OnImportContainerProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       ImportContainerProgressStatus status,
       int progress_percent,
       uint64_t progress_speed,
@@ -104,7 +105,7 @@
 class UpgradeContainerProgressObserver {
  public:
   virtual void OnUpgradeContainerProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       UpgradeContainerProgressStatus status,
       const std::vector<std::string>& messages) = 0;
 };
@@ -120,26 +121,27 @@
 class CrostiniContainerPropertiesObserver : public base::CheckedObserver {
  public:
   // Called when a container's OS release version changes.
-  virtual void OnContainerOsReleaseChanged(const ContainerId& container_id,
-                                           bool can_upgrade) = 0;
+  virtual void OnContainerOsReleaseChanged(
+      const guest_os::GuestId& container_id,
+      bool can_upgrade) = 0;
 };
 
 class ContainerStartedObserver : public base::CheckedObserver {
  public:
   // Called when the container has started.
-  virtual void OnContainerStarted(const ContainerId& container_id) = 0;
+  virtual void OnContainerStarted(const guest_os::GuestId& container_id) = 0;
 };
 
 class ContainerShutdownObserver : public base::CheckedObserver {
  public:
   // Called when the container has shutdown.
-  virtual void OnContainerShutdown(const ContainerId& container_id) = 0;
+  virtual void OnContainerShutdown(const guest_os::GuestId& container_id) = 0;
 };
 
 class CrostiniFileChangeObserver : public base::CheckedObserver {
  public:
   // Called when a path registered via AddFileWatch() is changed.
-  virtual void OnCrostiniFileChanged(const ContainerId& container_id,
+  virtual void OnCrostiniFileChanged(const guest_os::GuestId& container_id,
                                      const base::FilePath& path) = 0;
 };
 
@@ -299,7 +301,7 @@
   // Checks the arguments for creating an Lxd container via
   // CiceroneClient::CreateLxdContainer. |callback| is called immediately if the
   // arguments are bad, or once the container has been created.
-  void CreateLxdContainer(ContainerId container_id,
+  void CreateLxdContainer(guest_os::GuestId container_id,
                           absl::optional<std::string> opt_image_server_url,
                           absl::optional<std::string> opt_image_alias,
                           CrostiniResultCallback callback);
@@ -307,63 +309,64 @@
   // Checks the arguments for deleting an Lxd container via
   // CiceroneClient::DeleteLxdContainer. |callback| is called immediately if the
   // arguments are bad, or once the container has been deleted.
-  void DeleteLxdContainer(ContainerId container_id, BoolCallback callback);
+  void DeleteLxdContainer(guest_os::GuestId container_id,
+                          BoolCallback callback);
 
   // Checks the arguments for starting an Lxd container via
   // CiceroneClient::StartLxdContainer. |callback| is called immediately if the
   // arguments are bad, or once the container has been created.
-  void StartLxdContainer(ContainerId container_id,
+  void StartLxdContainer(guest_os::GuestId container_id,
                          CrostiniResultCallback callback);
 
   // Checks the arguments for stopping an Lxd container via
   // CiceroneClient::StopLxdContainer. |callback| is called immediately if the
   // arguments are bad, or once the container has been stopped.
-  void StopLxdContainer(ContainerId container_id,
+  void StopLxdContainer(guest_os::GuestId container_id,
                         CrostiniResultCallback callback);
 
   // Checks the arguments for setting up an Lxd container user via
   // CiceroneClient::SetUpLxdContainerUser. |callback| is called immediately if
   // the arguments are bad, or once garcon has been started.
-  void SetUpLxdContainerUser(ContainerId container_id,
+  void SetUpLxdContainerUser(guest_os::GuestId container_id,
                              std::string container_username,
                              BoolCallback callback);
 
   // Checks the arguments for exporting an Lxd container via
   // CiceroneClient::ExportLxdContainer. |callback| is called immediately if the
   // arguments are bad, or after the method call finishes.
-  void ExportLxdContainer(ContainerId container_id,
+  void ExportLxdContainer(guest_os::GuestId container_id,
                           base::FilePath export_path,
                           ExportLxdContainerResultCallback callback);
 
   // Checks the arguments for importing an Lxd container via
   // CiceroneClient::ImportLxdContainer. |callback| is called immediately if the
   // arguments are bad, or after the method call finishes.
-  void ImportLxdContainer(ContainerId container_id,
+  void ImportLxdContainer(guest_os::GuestId container_id,
                           base::FilePath import_path,
                           CrostiniResultCallback callback);
 
   // Checks the arguments for cancelling a Lxd container export via
   // CiceroneClient::CancelExportLxdContainer .
-  void CancelExportLxdContainer(ContainerId key);
+  void CancelExportLxdContainer(guest_os::GuestId key);
 
   // Checks the arguments for cancelling a Lxd container import via
   // CiceroneClient::CancelImportLxdContainer.
-  void CancelImportLxdContainer(ContainerId key);
+  void CancelImportLxdContainer(guest_os::GuestId key);
 
   // Checks the arguments for upgrading an existing container via
   // CiceroneClient::UpgradeContainer. An UpgradeProgressObserver should be used
   // to monitor further results.
-  void UpgradeContainer(const ContainerId& key,
+  void UpgradeContainer(const guest_os::GuestId& key,
                         ContainerVersion target_version,
                         CrostiniResultCallback callback);
 
   // Checks the arguments for canceling the upgrade of an existing container via
   // CiceroneClient::CancelUpgradeContainer.
-  void CancelUpgradeContainer(const ContainerId& key,
+  void CancelUpgradeContainer(const guest_os::GuestId& key,
                               CrostiniResultCallback callback);
 
   // Asynchronously launches an app as specified by its desktop file id.
-  void LaunchContainerApplication(const ContainerId& container_id,
+  void LaunchContainerApplication(const guest_os::GuestId& container_id,
                                   std::string desktop_file_id,
                                   const std::vector<std::string>& files,
                                   bool display_scaled,
@@ -373,7 +376,7 @@
   // |callback| is called after the method call finishes.
   using GetContainerAppIconsCallback =
       base::OnceCallback<void(bool success, const std::vector<Icon>& icons)>;
-  void GetContainerAppIcons(const ContainerId& container_id,
+  void GetContainerAppIcons(const guest_os::GuestId& container_id,
                             std::vector<std::string> desktop_file_ids,
                             int icon_size,
                             int scale,
@@ -383,7 +386,7 @@
   // container.
   using GetLinuxPackageInfoCallback =
       base::OnceCallback<void(const LinuxPackageInfo&)>;
-  void GetLinuxPackageInfo(const ContainerId& container_id,
+  void GetLinuxPackageInfo(const guest_os::GuestId& container_id,
                            std::string package_path,
                            GetLinuxPackageInfoCallback callback);
 
@@ -391,7 +394,7 @@
   // installation is successfully started, further updates will be sent to
   // added LinuxPackageOperationProgressObservers.
   using InstallLinuxPackageCallback = CrostiniResultCallback;
-  void InstallLinuxPackage(const ContainerId& container_id,
+  void InstallLinuxPackage(const guest_os::GuestId& container_id,
                            std::string package_path,
                            InstallLinuxPackageCallback callback);
 
@@ -400,7 +403,7 @@
   // added LinuxPackageOperationProgressObservers. Uses a package_id, given
   // by "package_name;version;arch;data", to identify the package to install
   // from the APT repository.
-  void InstallLinuxPackageFromApt(const ContainerId& container_id,
+  void InstallLinuxPackageFromApt(const guest_os::GuestId& container_id,
                                   std::string package_id,
                                   InstallLinuxPackageCallback callback);
 
@@ -409,7 +412,7 @@
   // to avoid problems with stale package_ids (such as after upgrades). If the
   // uninstallation is successfully started, further updates will be sent to
   // added LinuxPackageOperationProgressObservers.
-  void UninstallPackageOwningFile(const ContainerId& container_id,
+  void UninstallPackageOwningFile(const guest_os::GuestId& container_id,
                                   std::string desktop_file_id,
                                   CrostiniResultCallback callback);
 
@@ -421,16 +424,16 @@
                               const std::string& container_public_key,
                               const std::string& host_private_key,
                               const std::string& hostname)>;
-  void GetContainerSshKeys(const ContainerId& container_id,
+  void GetContainerSshKeys(const guest_os::GuestId& container_id,
                            GetContainerSshKeysCallback callback);
 
   // Add a relative path to watch within the container homedir. Register as a
   // CrostiniFileChangeObserver to be notified when changes occur. Used by
   // FilesApp.
-  void AddFileWatch(const ContainerId& container_id,
+  void AddFileWatch(const guest_os::GuestId& container_id,
                     const base::FilePath& path,
                     BoolCallback callback);
-  void RemoveFileWatch(const ContainerId& container_id,
+  void RemoveFileWatch(const guest_os::GuestId& container_id,
                        const base::FilePath& path);
   void AddFileChangeObserver(CrostiniFileChangeObserver* observer);
   void RemoveFileChangeObserver(CrostiniFileChangeObserver* observer);
@@ -440,7 +443,7 @@
       base::OnceCallback<void(bool success,
                               const std::string& failure_reason,
                               int32_t container_shell_pid)>;
-  void GetVshSession(const ContainerId& container_id,
+  void GetVshSession(const guest_os::GuestId& container_id,
                      int32_t host_vsh_pid,
                      VshSessionCallback callback);
 
@@ -448,11 +451,11 @@
   // The optional |observer| tracks progress. If provided, it must be alive
   // until the restart completes (i.e. when |callback| is called) or the request
   // is cancelled via |CancelRestartCrostini|.
-  RestartId RestartCrostini(ContainerId container_id,
+  RestartId RestartCrostini(guest_os::GuestId container_id,
                             CrostiniResultCallback callback,
                             RestartObserver* observer = nullptr);
 
-  RestartId RestartCrostiniWithOptions(ContainerId container_id,
+  RestartId RestartCrostiniWithOptions(guest_os::GuestId container_id,
                                        RestartOptions options,
                                        CrostiniResultCallback callback,
                                        RestartObserver* observer = nullptr);
@@ -468,7 +471,7 @@
   bool IsRestartPending(RestartId restart_id);
 
   // Adds a callback to receive notification of container shutdown.
-  void AddShutdownContainerCallback(ContainerId container_id,
+  void AddShutdownContainerCallback(guest_os::GuestId container_id,
                                     base::OnceClosure shutdown_callback);
 
   // Adds a callback to receive uninstall notification.
@@ -589,13 +592,13 @@
   void AddRunningVmForTesting(std::string vm_name);
   void AddStoppingVmForTesting(std::string vm_name);
 
-  void SetContainerOsRelease(const ContainerId& container_id,
+  void SetContainerOsRelease(const guest_os::GuestId& container_id,
                              const vm_tools::cicerone::OsRelease& os_release);
   const vm_tools::cicerone::OsRelease* GetContainerOsRelease(
-      const ContainerId& container_id) const;
+      const guest_os::GuestId& container_id) const;
   // Returns null if VM or container is not running.
   absl::optional<ContainerInfo> GetContainerInfo(
-      const ContainerId& container_id);
+      const guest_os::GuestId& container_id);
   void AddRunningContainerForTesting(std::string vm_name, ContainerInfo info);
 
   // If the Crostini reporting policy is set, save the last app launch
@@ -628,14 +631,15 @@
   void AddContainerShutdownObserver(ContainerShutdownObserver* observer);
   void RemoveContainerShutdownObserver(ContainerShutdownObserver* observer);
 
-  bool IsContainerUpgradeable(const ContainerId& container_id) const;
-  bool ShouldPromptContainerUpgrade(const ContainerId& container_id) const;
-  void UpgradePromptShown(const ContainerId& container_id);
+  bool IsContainerUpgradeable(const guest_os::GuestId& container_id) const;
+  bool ShouldPromptContainerUpgrade(
+      const guest_os::GuestId& container_id) const;
+  void UpgradePromptShown(const guest_os::GuestId& container_id);
   bool IsUncleanStartup() const;
   void SetUncleanStartupForTesting(bool is_unclean_startup);
   void RemoveUncleanSshfsMounts();
   void DeallocateForwardedPortsCallback(Profile* profile,
-                                        const ContainerId& container_id);
+                                        const guest_os::GuestId& container_id);
 
   void CallRestarterStartLxdContainerFinishedForTesting(
       CrostiniManager::RestartId id,
@@ -649,7 +653,7 @@
   // mounted. If this is something running in the background set background to
   // true, if failures are user-visible set it to false. If you're setting
   // base::DoNothing as the callback then background should be true.
-  void MountCrostiniFiles(ContainerId container_id,
+  void MountCrostiniFiles(guest_os::GuestId container_id,
                           CrostiniResultCallback callback,
                           bool background);
 
@@ -716,54 +720,54 @@
   // is still being created, in which case we will wait for an
   // OnLxdContainerCreated event.
   void OnCreateLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniResultCallback callback,
       absl::optional<vm_tools::cicerone::CreateLxdContainerResponse> response);
 
   // Callback for CiceroneClient::DeleteLxdContainer.
   void OnDeleteLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       BoolCallback callback,
       absl::optional<vm_tools::cicerone::DeleteLxdContainerResponse> response);
 
   // Callback for CiceroneClient::StartLxdContainer.
   void OnStartLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniResultCallback callback,
       absl::optional<vm_tools::cicerone::StartLxdContainerResponse> response);
 
   // Callback for CiceroneClient::StopLxdContainer.
   void OnStopLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniResultCallback callback,
       absl::optional<vm_tools::cicerone::StopLxdContainerResponse> response);
 
   // Callback for CiceroneClient::SetUpLxdContainerUser.
   void OnSetUpLxdContainerUser(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       BoolCallback callback,
       absl::optional<vm_tools::cicerone::SetUpLxdContainerUserResponse>
           response);
 
   // Callback for CiceroneClient::ExportLxdContainer.
   void OnExportLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       absl::optional<vm_tools::cicerone::ExportLxdContainerResponse> response);
 
   // Callback for CiceroneClient::ImportLxdContainer.
   void OnImportLxdContainer(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       absl::optional<vm_tools::cicerone::ImportLxdContainerResponse> response);
 
   // Callback for CiceroneClient::CancelExportLxdContainer.
   void OnCancelExportLxdContainer(
-      const ContainerId& key,
+      const guest_os::GuestId& key,
       absl::optional<vm_tools::cicerone::CancelExportLxdContainerResponse>
           response);
 
   // Callback for CiceroneClient::CancelImportLxdContainer.
   void OnCancelImportLxdContainer(
-      const ContainerId& key,
+      const guest_os::GuestId& key,
       absl::optional<vm_tools::cicerone::CancelImportLxdContainerResponse>
           response);
 
@@ -840,15 +844,15 @@
   void EmitVmDiskTypeMetric(const std::string vm_name);
 
   // Removes specified container id from running_containers list.
-  void RemoveStoppedContainer(const ContainerId& container_id);
+  void RemoveStoppedContainer(const guest_os::GuestId& container_id);
 
   // Registers a container with GuestOsService's registries. No-op if it's
   // already registered.
-  void RegisterContainer(const ContainerId& container_id);
+  void RegisterContainer(const guest_os::GuestId& container_id);
 
   // Unregisters a container from GuestOsService's registries. No-op if it's
   // not registered.
-  void UnregisterContainer(const ContainerId& container_id);
+  void UnregisterContainer(const guest_os::GuestId& container_id);
 
   // Unregisters all container from GuestOsService's registries.
   void UnregisterAllContainers();
@@ -868,15 +872,20 @@
   bool is_unclean_startup_ = false;
 
   // Callbacks that are waiting on a signal
-  std::multimap<ContainerId, CrostiniResultCallback> start_container_callbacks_;
-  std::multimap<ContainerId, CrostiniResultCallback> stop_container_callbacks_;
-  std::multimap<ContainerId, base::OnceClosure> shutdown_container_callbacks_;
-  std::multimap<ContainerId, CrostiniResultCallback>
+  std::multimap<guest_os::GuestId, CrostiniResultCallback>
+      start_container_callbacks_;
+  std::multimap<guest_os::GuestId, CrostiniResultCallback>
+      stop_container_callbacks_;
+  std::multimap<guest_os::GuestId, base::OnceClosure>
+      shutdown_container_callbacks_;
+  std::multimap<guest_os::GuestId, CrostiniResultCallback>
       create_lxd_container_callbacks_;
-  std::multimap<ContainerId, BoolCallback> delete_lxd_container_callbacks_;
-  std::map<ContainerId, ExportLxdContainerResultCallback>
+  std::multimap<guest_os::GuestId, BoolCallback>
+      delete_lxd_container_callbacks_;
+  std::map<guest_os::GuestId, ExportLxdContainerResultCallback>
       export_lxd_container_callbacks_;
-  std::map<ContainerId, CrostiniResultCallback> import_lxd_container_callbacks_;
+  std::map<guest_os::GuestId, CrostiniResultCallback>
+      import_lxd_container_callbacks_;
 
   // Callbacks to run after Tremplin is started, keyed by vm_name. These are
   // used if StartTerminaVm completes but we need to wait from Tremplin to
@@ -892,10 +901,11 @@
   // Running containers as keyed by vm name.
   std::multimap<std::string, ContainerInfo> running_containers_;
 
-  // OsRelease protos keyed by ContainerId. We populate this map even if a
+  // OsRelease protos keyed by guest_os::GuestId. We populate this map even if a
   // container fails to start normally.
-  std::map<ContainerId, vm_tools::cicerone::OsRelease> container_os_releases_;
-  std::set<ContainerId> container_upgrade_prompt_shown_;
+  std::map<guest_os::GuestId, vm_tools::cicerone::OsRelease>
+      container_os_releases_;
+  std::set<guest_os::GuestId> container_upgrade_prompt_shown_;
 
   std::vector<RemoveCrostiniCallback> remove_crostini_callbacks_;
 
@@ -917,9 +927,9 @@
   base::ObserverList<ash::VmStartingObserver> vm_starting_observers_;
 
   // RestartIds present in |restarters_by_id_| will always have a restarter in
-  // |restarters_by_container_| for the corresponding ContainerId.
-  std::map<CrostiniManager::RestartId, ContainerId> restarters_by_id_;
-  std::map<ContainerId, std::unique_ptr<CrostiniRestarter>>
+  // |restarters_by_container_| for the corresponding guest_os::GuestId.
+  std::map<CrostiniManager::RestartId, guest_os::GuestId> restarters_by_id_;
+  std::map<guest_os::GuestId, std::unique_ptr<CrostiniRestarter>>
       restarters_by_container_;
   static RestartId next_restart_id_;
 
@@ -956,7 +966,8 @@
 
   std::unique_ptr<CrostiniSshfs> crostini_sshfs_;
 
-  base::flat_map<ContainerId, guest_os::GuestOsTerminalProviderRegistry::Id>
+  base::flat_map<guest_os::GuestId,
+                 guest_os::GuestOsTerminalProviderRegistry::Id>
       terminal_provider_ids_;
 
   // Note: This should remain the last member so it'll be destroyed and
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
index 56714d2..3d9211e 100644
--- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -280,7 +280,7 @@
   base::RunLoop* run_loop() { return run_loop_.get(); }
   Profile* profile() { return profile_.get(); }
   CrostiniManager* crostini_manager() { return crostini_manager_; }
-  const ContainerId& container_id() { return container_id_; }
+  const guest_os::GuestId& container_id() { return container_id_; }
 
   ash::FakeChromeUserManager* fake_user_manager() const {
     return static_cast<ash::FakeChromeUserManager*>(
@@ -296,7 +296,8 @@
       run_loop_;  // run_loop_ must be created on the UI thread.
   std::unique_ptr<TestingProfile> profile_;
   CrostiniManager* crostini_manager_;
-  const ContainerId container_id_ = ContainerId(kVmName, kContainerName);
+  const guest_os::GuestId container_id_ =
+      guest_os::GuestId(kVmName, kContainerName);
   device::FakeUsbDeviceManager fake_usb_manager_;
   base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
@@ -2387,17 +2388,19 @@
 
   // AnsibleManagementService::Observer
   void OnAnsibleSoftwareConfigurationStarted(
-      const ContainerId& container_id) override {}
-  void OnAnsibleSoftwareConfigurationFinished(const ContainerId& container_id,
-                                              bool success) override {}
-  void OnAnsibleSoftwareInstall(const ContainerId& container_id) override {
+      const guest_os::GuestId& container_id) override {}
+  void OnAnsibleSoftwareConfigurationFinished(
+      const guest_os::GuestId& container_id,
+      bool success) override {}
+  void OnAnsibleSoftwareInstall(
+      const guest_os::GuestId& container_id) override {
     if (is_install_ansible_success_) {
       ansible_management_test_helper_->SendSucceededInstallSignal();
     } else {
       ansible_management_test_helper_->SendFailedInstallSignal();
     }
   }
-  void OnApplyAnsiblePlaybook(const ContainerId& container_id) override {
+  void OnApplyAnsiblePlaybook(const guest_os::GuestId& container_id) override {
     if (is_apply_ansible_success_) {
       ansible_management_test_helper_->SendSucceededApplySignal();
     } else {
@@ -2527,7 +2530,7 @@
  protected:
   // UpgradeContainerProgressObserver
   void OnUpgradeContainerProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       UpgradeContainerProgressStatus status,
       const std::vector<std::string>& messages) override {
     if (status == final_status_) {
@@ -2535,7 +2538,7 @@
     }
   }
 
-  ContainerId container_id_ = ContainerId(kVmName, kContainerName);
+  guest_os::GuestId container_id_ = guest_os::GuestId(kVmName, kContainerName);
 
   UpgradeContainerProgressStatus final_status_ =
       UpgradeContainerProgressStatus::FAILED;
diff --git a/chrome/browser/ash/crostini/crostini_package_notification.cc b/chrome/browser/ash/crostini/crostini_package_notification.cc
index 72c7949..77537a93 100644
--- a/chrome/browser/ash/crostini/crostini_package_notification.cc
+++ b/chrome/browser/ash/crostini/crostini_package_notification.cc
@@ -47,7 +47,7 @@
     Profile* profile,
     NotificationType notification_type,
     PackageOperationStatus status,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const std::u16string& app_name,
     const std::string& notification_id,
     CrostiniPackageService* package_service)
diff --git a/chrome/browser/ash/crostini/crostini_package_notification.h b/chrome/browser/ash/crostini/crostini_package_notification.h
index e74d200..598e718 100644
--- a/chrome/browser/ash/crostini/crostini_package_notification.h
+++ b/chrome/browser/ash/crostini/crostini_package_notification.h
@@ -37,7 +37,7 @@
   CrostiniPackageNotification(Profile* profile,
                               NotificationType notification_type,
                               PackageOperationStatus status,
-                              const ContainerId& container_id,
+                              const guest_os::GuestId& container_id,
                               const std::u16string& app_name,
                               const std::string& notification_id,
                               CrostiniPackageService* installer_service);
@@ -126,7 +126,7 @@
   // launched.
   std::string app_id_;
 
-  ContainerId container_id_;
+  guest_os::GuestId container_id_;
 
   std::set<std::string> inserted_apps_;
   int app_count_ = 0;
diff --git a/chrome/browser/ash/crostini/crostini_package_notification_unittest.cc b/chrome/browser/ash/crostini/crostini_package_notification_unittest.cc
index 5f7afc21..540fe8a2 100644
--- a/chrome/browser/ash/crostini/crostini_package_notification_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_package_notification_unittest.cc
@@ -117,7 +117,7 @@
       profile_.get(),
       CrostiniPackageNotification::NotificationType::PACKAGE_INSTALL,
       PackageOperationStatus::RUNNING,
-      ContainerId(kCrostiniDefaultVmName, kCrostiniDefaultContainerName),
+      guest_os::GuestId(kCrostiniDefaultVmName, kCrostiniDefaultContainerName),
       std::u16string(), kNotificationId, service_.get());
 
   app = CrostiniTestHelper::BasicApp(kSecondAppFileId);
@@ -132,7 +132,7 @@
       profile_.get(),
       CrostiniPackageNotification::NotificationType::PACKAGE_INSTALL,
       PackageOperationStatus::RUNNING,
-      ContainerId(kCrostiniDefaultVmName, kCrostiniDefaultContainerName),
+      guest_os::GuestId(kCrostiniDefaultVmName, kCrostiniDefaultContainerName),
       std::u16string(), kNotificationId, service_.get());
 
   // Initially, the error message is blank.
diff --git a/chrome/browser/ash/crostini/crostini_package_service.cc b/chrome/browser/ash/crostini/crostini_package_service.cc
index 7e8146e4..692d3f07 100644
--- a/chrome/browser/ash/crostini/crostini_package_service.cc
+++ b/chrome/browser/ash/crostini/crostini_package_service.cc
@@ -166,7 +166,7 @@
 }
 
 void CrostiniPackageService::GetLinuxPackageInfo(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const storage::FileSystemURL& package_url,
     CrostiniManager::GetLinuxPackageInfoCallback callback) {
   base::FilePath path;
@@ -194,7 +194,7 @@
 }
 
 void CrostiniPackageService::OnSharePathForGetLinuxPackageInfo(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const storage::FileSystemURL& package_url,
     const base::FilePath& package_path,
     CrostiniManager::GetLinuxPackageInfoCallback callback,
@@ -215,7 +215,7 @@
 }
 
 void CrostiniPackageService::QueueInstallLinuxPackage(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const storage::FileSystemURL& package_url,
     CrostiniManager::InstallLinuxPackageCallback callback) {
   base::FilePath path;
@@ -245,7 +245,7 @@
 }
 
 void CrostiniPackageService::OnInstallLinuxPackageProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     InstallLinuxPackageProgressStatus status,
     int progress_percent,
     const std::string& error_message) {
@@ -262,7 +262,7 @@
 }
 
 void CrostiniPackageService::OnUninstallPackageProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     UninstallPackageProgressStatus status,
     int progress_percent) {
   UpdatePackageOperationStatus(
@@ -273,7 +273,7 @@
   // Making a notification as failed removes it from |running_notifications_|,
   // which invalidates the iterators. To avoid this, we record all the
   // containers that just shut down before removing any notifications.
-  std::vector<ContainerId> to_remove;
+  std::vector<guest_os::GuestId> to_remove;
   for (auto& running_notification : running_notifications_) {
     if (running_notification.first.vm_name == vm_name) {
       to_remove.push_back(running_notification.first);
@@ -299,8 +299,8 @@
     return;
   }
 
-  const ContainerId container_id(registration->VmName(),
-                                 registration->ContainerName());
+  const guest_os::GuestId container_id(registration->VmName(),
+                                       registration->ContainerName());
   const std::string app_name = registration->Name();
   if (ContainerHasRunningOperation(container_id)) {
     CreateQueuedUninstall(container_id, app_id, app_name);
@@ -316,12 +316,12 @@
 }
 
 bool CrostiniPackageService::ContainerHasRunningOperation(
-    const ContainerId& container_id) const {
+    const guest_os::GuestId& container_id) const {
   return base::Contains(running_notifications_, container_id);
 }
 
 bool CrostiniPackageService::ContainerHasQueuedOperation(
-    const ContainerId& container_id) const {
+    const guest_os::GuestId& container_id) const {
   return (base::Contains(queued_installs_, container_id) &&
           !queued_installs_.at(container_id).empty()) ||
          (base::Contains(queued_uninstalls_, container_id) &&
@@ -329,7 +329,7 @@
 }
 
 void CrostiniPackageService::CreateRunningNotification(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniPackageNotification::NotificationType notification_type,
     const std::string& app_name) {
   {  // Scope limit for |it|, which will become invalid shortly.
@@ -354,7 +354,7 @@
 }
 
 void CrostiniPackageService::CreateQueuedUninstall(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const std::string& app_id,
     const std::string& app_name) {
   queued_uninstalls_[container_id].emplace(
@@ -367,7 +367,7 @@
 }
 
 void CrostiniPackageService::CreateQueuedInstall(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const std::string& package,
     CrostiniManager::InstallLinuxPackageCallback callback) {
   queued_installs_[container_id].emplace(
@@ -380,7 +380,7 @@
 }
 
 void CrostiniPackageService::UpdatePackageOperationStatus(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     PackageOperationStatus status,
     int progress_percent,
     const std::string& error_message) {
@@ -421,7 +421,7 @@
 }
 
 void CrostiniPackageService::OnPendingAppListUpdates(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     int count) {
   if (count != 0) {
     has_pending_app_list_updates_.insert(container_id);
@@ -441,14 +441,14 @@
 }
 
 void CrostiniPackageService::OnGetLinuxPackageInfo(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniManager::GetLinuxPackageInfoCallback callback,
     const LinuxPackageInfo& linux_package_info) {
   std::move(callback).Run(linux_package_info);
 }
 
 void CrostiniPackageService::OnInstallLinuxPackage(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniManager::InstallLinuxPackageCallback callback,
     CrostiniResult result) {
   std::move(callback).Run(result);
@@ -461,8 +461,8 @@
 void CrostiniPackageService::UninstallApplication(
     const guest_os::GuestOsRegistryService::Registration& registration,
     const std::string& app_id) {
-  const ContainerId container_id(registration.VmName(),
-                                 registration.ContainerName());
+  const guest_os::GuestId container_id(registration.VmName(),
+                                       registration.ContainerName());
 
   // Policies can change under us, and crostini may now be forbidden.
   if (!CrostiniFeatures::Get()->IsAllowedNow(profile_)) {
@@ -482,7 +482,7 @@
 }
 
 void CrostiniPackageService::OnCrostiniRunningForUninstall(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     const std::string& desktop_file_id,
     CrostiniResult result) {
   if (result != CrostiniResult::SUCCESS) {
@@ -498,7 +498,7 @@
 }
 
 void CrostiniPackageService::OnUninstallPackageOwningFile(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     CrostiniResult result) {
   if (result != CrostiniResult::SUCCESS) {
     // Let user know the uninstall failed.
@@ -511,7 +511,7 @@
 }
 
 void CrostiniPackageService::StartQueuedOperation(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   auto uninstall_queue_iter = queued_uninstalls_.find(container_id);
   if (uninstall_queue_iter != queued_uninstalls_.end() &&
       !uninstall_queue_iter->second.empty()) {
diff --git a/chrome/browser/ash/crostini/crostini_package_service.h b/chrome/browser/ash/crostini/crostini_package_service.h
index 813c0cb..e85dd90 100644
--- a/chrome/browser/ash/crostini/crostini_package_service.h
+++ b/chrome/browser/ash/crostini/crostini_package_service.h
@@ -53,22 +53,22 @@
   void NotificationCompleted(CrostiniPackageNotification* notification);
 
   void GetLinuxPackageInfo(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       const storage::FileSystemURL& package_url,
       CrostiniManager::GetLinuxPackageInfoCallback callback);
 
   // LinuxPackageOperationProgressObserver:
-  void OnInstallLinuxPackageProgress(const ContainerId& container_id,
+  void OnInstallLinuxPackageProgress(const guest_os::GuestId& container_id,
                                      InstallLinuxPackageProgressStatus status,
                                      int progress_percent,
                                      const std::string& error_message) override;
 
-  void OnUninstallPackageProgress(const ContainerId& container_id,
+  void OnUninstallPackageProgress(const guest_os::GuestId& container_id,
                                   UninstallPackageProgressStatus status,
                                   int progress_percent) override;
 
   // PendingAppListUpdatesObserver:
-  void OnPendingAppListUpdates(const ContainerId& container_id,
+  void OnPendingAppListUpdates(const guest_os::GuestId& container_id,
                                int count) override;
 
   // ash::VmShutdownObserver
@@ -77,7 +77,7 @@
   // (Eventually) install a Linux package. If successfully started, a system
   // notification will be used to display further updates.
   void QueueInstallLinuxPackage(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       const storage::FileSystemURL& package_url,
       CrostiniManager::InstallLinuxPackageCallback callback);
 
@@ -92,8 +92,9 @@
   struct QueuedInstall;
   struct QueuedUninstall;
 
-  bool ContainerHasRunningOperation(const ContainerId& container_id) const;
-  bool ContainerHasQueuedOperation(const ContainerId& container_id) const;
+  bool ContainerHasRunningOperation(
+      const guest_os::GuestId& container_id) const;
+  bool ContainerHasQueuedOperation(const guest_os::GuestId& container_id) const;
 
   // Creates a new notification and adds it to running_notifications_.
   // |app_name| is the name of the application being modified, if any -- for
@@ -102,18 +103,18 @@
   // If there is a running notification, it will be set to error state. Caller
   // should check before calling this if a different behavior is desired.
   void CreateRunningNotification(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniPackageNotification::NotificationType notification_type,
       const std::string& app_name);
 
   // Creates a new uninstall notification and adds it to queued_uninstalls_.
-  void CreateQueuedUninstall(const ContainerId& container_id,
+  void CreateQueuedUninstall(const guest_os::GuestId& container_id,
                              const std::string& app_id,
                              const std::string& app_name);
 
   // Creates a new install notification and adds it to queued_installs_.
   void CreateQueuedInstall(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       const std::string& package,
       CrostiniManager::InstallLinuxPackageCallback callback);
 
@@ -122,14 +123,14 @@
   // Note that if status is |SUCCEEDED| or |FAILED|, this may kick off another
   // operation from the queued_uninstalls_ list. When status is |FAILED|, the
   // |error_message| will contain an error reported by the installation process.
-  void UpdatePackageOperationStatus(const ContainerId& container_id,
+  void UpdatePackageOperationStatus(const guest_os::GuestId& container_id,
                                     PackageOperationStatus status,
                                     int progress_percent,
                                     const std::string& error_message = {});
 
   // Callback between sharing and invoking GetLinuxPackageInfo().
   void OnSharePathForGetLinuxPackageInfo(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       const storage::FileSystemURL& package_url,
       const base::FilePath& package_path,
       CrostiniManager::GetLinuxPackageInfoCallback callback,
@@ -138,13 +139,13 @@
 
   // Wraps the callback provided in GetLinuxPackageInfo().
   void OnGetLinuxPackageInfo(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniManager::GetLinuxPackageInfoCallback callback,
       const LinuxPackageInfo& linux_package_info);
 
   // Wraps the callback provided in InstallLinuxPackage().
   void OnInstallLinuxPackage(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       CrostiniManager::InstallLinuxPackageCallback callback,
       CrostiniResult result);
 
@@ -157,30 +158,30 @@
 
   // Callback when the Crostini container is up and ready to accept messages.
   // Used by the uninstall flow only.
-  void OnCrostiniRunningForUninstall(const ContainerId& container_id,
+  void OnCrostiniRunningForUninstall(const guest_os::GuestId& container_id,
                                      const std::string& desktop_file_id,
                                      CrostiniResult result);
 
   // Callback for CrostiniManager::UninstallPackageOwningFile().
-  void OnUninstallPackageOwningFile(const ContainerId& container_id,
+  void OnUninstallPackageOwningFile(const guest_os::GuestId& container_id,
                                     CrostiniResult result);
 
   // Kick off the next operation in the queue for the given container.
-  void StartQueuedOperation(const ContainerId& container_id);
+  void StartQueuedOperation(const guest_os::GuestId& container_id);
 
   std::string GetUniqueNotificationId();
 
   Profile* profile_;
 
   // The notifications in the RUNNING state for each container.
-  std::map<ContainerId, std::unique_ptr<CrostiniPackageNotification>>
+  std::map<guest_os::GuestId, std::unique_ptr<CrostiniPackageNotification>>
       running_notifications_;
 
   // Installs we want to run when the current operation is done.
-  std::map<ContainerId, std::queue<QueuedInstall>> queued_installs_;
+  std::map<guest_os::GuestId, std::queue<QueuedInstall>> queued_installs_;
 
   // Uninstalls we want to run when the current operation is done.
-  std::map<ContainerId, std::queue<QueuedUninstall>> queued_uninstalls_;
+  std::map<guest_os::GuestId, std::queue<QueuedUninstall>> queued_uninstalls_;
 
   // Notifications in a finished state (either SUCCEEDED or FAILED). We need
   // to keep notifications around until they are dismissed even if we don't
@@ -191,7 +192,7 @@
   // A map storing which containers have currently pending app list update
   // operations. If a container is not present in the map, we assume no pending
   // updates.
-  std::set<ContainerId> has_pending_app_list_updates_;
+  std::set<guest_os::GuestId> has_pending_app_list_updates_;
 
   // Called each time a notification is set to a new state.
   StateChangeCallback testing_state_change_callback_;
diff --git a/chrome/browser/ash/crostini/crostini_package_service_unittest.cc b/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
index 122f21f..67755486 100644
--- a/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_package_service_unittest.cc
@@ -246,8 +246,8 @@
                                                 // kDifferentContainerAppFileId.
   const std::string kDifferentContainerApp2Id;  // App_id for app with
                                                 // kDifferentContainerApp2FileId
-  const ContainerId kDifferentContainerId =
-      ContainerId(kDifferentVmVmName, kDifferentContainerContainerName);
+  const guest_os::GuestId kDifferentContainerId =
+      guest_os::GuestId(kDifferentVmVmName, kDifferentContainerContainerName);
   storage::FileSystemURL package_file_url_;
 
   UninstallPackageProgressSignal MakeUninstallSignal(
@@ -268,7 +268,8 @@
     return signal;
   }
 
-  void SendAppListUpdateSignal(const ContainerId& container_id, int count) {
+  void SendAppListUpdateSignal(const guest_os::GuestId& container_id,
+                               int count) {
     PendingAppListUpdatesSignal signal;
     signal.set_vm_name(container_id.vm_name);
     signal.set_container_name(container_id.container_name);
@@ -1079,7 +1080,7 @@
   signal_progress2.set_status(UninstallPackageProgressSignal::SUCCEEDED);
 
   SendAppListUpdateSignal(
-      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
+      guest_os::GuestId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
   fake_cicerone_client_->UninstallPackageProgress(signal_progress);
   fake_cicerone_client_->UninstallPackageProgress(signal_progress2);
 
@@ -1096,7 +1097,7 @@
   service_->QueueUninstallApplication(kDefaultAppId);
 
   SendAppListUpdateSignal(
-      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
+      guest_os::GuestId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
 
   StartAndSignalUninstall(UninstallPackageProgressSignal::SUCCEEDED);
 
@@ -1831,7 +1832,7 @@
   signal_progress.set_status(InstallLinuxPackageProgressSignal::SUCCEEDED);
 
   service_->QueueInstallLinuxPackage(
-      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName),
+      guest_os::GuestId(kDifferentVmVmName, kCrostiniDefaultContainerName),
       package_file_url_, base::DoNothing());
   request =
       fake_cicerone_client_->get_most_recent_install_linux_package_request();
@@ -1842,7 +1843,7 @@
   base::RunLoop().RunUntilIdle();
 
   SendAppListUpdateSignal(
-      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
+      guest_os::GuestId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
   fake_cicerone_client_->InstallLinuxPackageProgress(signal_progress);
   fake_cicerone_client_->InstallLinuxPackageProgress(signal_progress2);
 
@@ -1861,7 +1862,7 @@
   base::RunLoop().RunUntilIdle();
 
   SendAppListUpdateSignal(
-      ContainerId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
+      guest_os::GuestId(kDifferentVmVmName, kCrostiniDefaultContainerName), 1);
 
   StartAndSignalInstall(InstallLinuxPackageProgressSignal::SUCCEEDED);
 
diff --git a/chrome/browser/ash/crostini/crostini_port_forwarder.cc b/chrome/browser/ash/crostini/crostini_port_forwarder.cc
index 323aa40..939e8fd 100644
--- a/chrome/browser/ash/crostini/crostini_port_forwarder.cc
+++ b/chrome/browser/ash/crostini/crostini_port_forwarder.cc
@@ -81,13 +81,13 @@
   return (port_number && port_number.value() == key.port_number) &&
          (protocol_type &&
           protocol_type.value() == static_cast<int>(key.protocol_type)) &&
-         ContainerId(dict) == ContainerId(key.container_id);
+         guest_os::GuestId(dict) == guest_os::GuestId(key.container_id);
 }
 
 bool CrostiniPortForwarder::MatchPortRuleContainerId(
     const base::Value& dict,
-    const ContainerId& container_id) {
-  return ContainerId(dict) == container_id;
+    const guest_os::GuestId& container_id) {
+  return guest_os::GuestId(dict) == container_id;
 }
 
 void CrostiniPortForwarder::AddNewPortPreference(const PortRuleKey& key,
@@ -155,7 +155,7 @@
 
 void CrostiniPortForwarder::TryActivatePort(
     const PortRuleKey& key,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::OnceCallback<void(bool)> result_callback) {
   auto info =
       CrostiniManager::GetForProfile(profile_)->GetContainerInfo(container_id);
@@ -202,7 +202,7 @@
 
 void CrostiniPortForwarder::TryDeactivatePort(
     const PortRuleKey& key,
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::OnceCallback<void(bool)> result_callback) {
   auto info =
       CrostiniManager::GetForProfile(profile_)->GetContainerInfo(container_id);
@@ -239,7 +239,7 @@
   }
 }
 
-void CrostiniPortForwarder::AddPort(const ContainerId& container_id,
+void CrostiniPortForwarder::AddPort(const guest_os::GuestId& container_id,
                                     uint16_t port_number,
                                     const Protocol& protocol_type,
                                     const std::string& label,
@@ -260,7 +260,7 @@
                std::move(result_callback));
 }
 
-void CrostiniPortForwarder::ActivatePort(const ContainerId& container_id,
+void CrostiniPortForwarder::ActivatePort(const guest_os::GuestId& container_id,
                                          uint16_t port_number,
                                          const Protocol& protocol_type,
                                          ResultCallback result_callback) {
@@ -290,10 +290,11 @@
                                          std::move(on_activate_port_completed));
 }
 
-void CrostiniPortForwarder::DeactivatePort(const ContainerId& container_id,
-                                           uint16_t port_number,
-                                           const Protocol& protocol_type,
-                                           ResultCallback result_callback) {
+void CrostiniPortForwarder::DeactivatePort(
+    const guest_os::GuestId& container_id,
+    uint16_t port_number,
+    const Protocol& protocol_type,
+    ResultCallback result_callback) {
   PortRuleKey existing_port_key = {
       .port_number = port_number,
       .protocol_type = protocol_type,
@@ -314,7 +315,7 @@
       existing_port_key, container_id, std::move(on_deactivate_port_completed));
 }
 
-void CrostiniPortForwarder::RemovePort(const ContainerId& container_id,
+void CrostiniPortForwarder::RemovePort(const guest_os::GuestId& container_id,
                                        uint16_t port_number,
                                        const Protocol& protocol_type,
                                        ResultCallback result_callback) {
@@ -339,7 +340,7 @@
 }
 
 void CrostiniPortForwarder::DeactivateAllActivePorts(
-    const ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   auto it = forwarded_ports_.begin();
   while (it != forwarded_ports_.end()) {
     if (it->first.container_id == container_id) {
@@ -352,7 +353,8 @@
   SignalActivePortsChanged();
 }
 
-void CrostiniPortForwarder::RemoveAllPorts(const ContainerId& container_id) {
+void CrostiniPortForwarder::RemoveAllPorts(
+    const guest_os::GuestId& container_id) {
   PrefService* pref_service = profile_->GetPrefs();
   ListPrefUpdate update(pref_service, crostini::prefs::kCrostiniPortForwarding);
   update->EraseListValueIf([&container_id, this](const auto& dict) {
diff --git a/chrome/browser/ash/crostini/crostini_port_forwarder.h b/chrome/browser/ash/crostini/crostini_port_forwarder.h
index ea58c5d6..3129c61 100644
--- a/chrome/browser/ash/crostini/crostini_port_forwarder.h
+++ b/chrome/browser/ash/crostini/crostini_port_forwarder.h
@@ -45,7 +45,7 @@
   struct PortRuleKey {
     uint16_t port_number;
     Protocol protocol_type;
-    ContainerId container_id;
+    guest_os::GuestId container_id;
 
     bool operator==(const PortRuleKey& other) const {
       return port_number == other.port_number &&
@@ -74,20 +74,20 @@
   // pass. This means a port setting has been successfully updated in the
   // iptables and the profile preference setting has also been successfully
   // updated.
-  void ActivatePort(const ContainerId& container_id,
+  void ActivatePort(const guest_os::GuestId& container_id,
                     uint16_t port_number,
                     const Protocol& protocol_type,
                     ResultCallback result_callback);
-  void AddPort(const ContainerId& container_id,
+  void AddPort(const guest_os::GuestId& container_id,
                uint16_t port_number,
                const Protocol& protocol_type,
                const std::string& label,
                ResultCallback result_callback);
-  void DeactivatePort(const ContainerId& container_id,
+  void DeactivatePort(const guest_os::GuestId& container_id,
                       uint16_t port_number,
                       const Protocol& protocol_type,
                       ResultCallback result_callback);
-  void RemovePort(const ContainerId& container_id,
+  void RemovePort(const guest_os::GuestId& container_id,
                   uint16_t port_number,
                   const Protocol& protocol_type,
                   ResultCallback result_callback);
@@ -97,12 +97,12 @@
 
   // Deactivate all ports belonging to the container_id and removes them from
   // the preferences.
-  void RemoveAllPorts(const ContainerId& container_id);
+  void RemoveAllPorts(const guest_os::GuestId& container_id);
 
   // Deactivate all active ports belonging to the container_id and set their
   // preference to inactive such that these ports will not be automatically
   // re-forwarded on re-startup. This is called on container shutdown.
-  void DeactivateAllActivePorts(const ContainerId& container_id);
+  void DeactivateAllActivePorts(const guest_os::GuestId& container_id);
 
   base::ListValue GetActivePorts();
 
@@ -128,7 +128,7 @@
   void SignalActivePortsChanged();
   bool MatchPortRuleDict(const base::Value& dict, const PortRuleKey& key);
   bool MatchPortRuleContainerId(const base::Value& dict,
-                                const ContainerId& container_id);
+                                const guest_os::GuestId& container_id);
   void AddNewPortPreference(const PortRuleKey& key, const std::string& label);
   bool RemovePortPreference(const PortRuleKey& key);
   absl::optional<base::Value> ReadPortPreference(const PortRuleKey& key);
@@ -140,10 +140,10 @@
                                          PortRuleKey key,
                                          bool success);
   void TryDeactivatePort(const PortRuleKey& key,
-                         const ContainerId& container_id,
+                         const guest_os::GuestId& container_id,
                          base::OnceCallback<void(bool)> result_callback);
   void TryActivatePort(const PortRuleKey& key,
-                       const ContainerId& container_id,
+                       const guest_os::GuestId& container_id,
                        base::OnceCallback<void(bool)> result_callback);
   void UpdateActivePortInterfaces();
 
diff --git a/chrome/browser/ash/crostini/crostini_port_forwarder_unittest.cc b/chrome/browser/ash/crostini/crostini_port_forwarder_unittest.cc
index fa29a5f4..023dc50 100644
--- a/chrome/browser/ash/crostini/crostini_port_forwarder_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_port_forwarder_unittest.cc
@@ -32,8 +32,8 @@
  public:
   CrostiniPortForwarderTest()
       : default_container_id_(DefaultContainerId()),
-        other_container_id_(ContainerId("other", "other")),
-        inactive_container_id_(ContainerId("inactive", "inactive")) {}
+        other_container_id_(guest_os::GuestId("other", "other")),
+        inactive_container_id_(guest_os::GuestId("inactive", "inactive")) {}
 
   CrostiniPortForwarderTest(const CrostiniPortForwarderTest&) = delete;
   CrostiniPortForwarderTest& operator=(const CrostiniPortForwarderTest&) =
@@ -83,9 +83,10 @@
 
   Profile* profile() { return profile_.get(); }
 
-  CrostiniPortForwarder::PortRuleKey GetPortKey(int port_number,
-                                                Protocol protocol_type,
-                                                ContainerId container_id) {
+  CrostiniPortForwarder::PortRuleKey GetPortKey(
+      int port_number,
+      Protocol protocol_type,
+      guest_os::GuestId container_id) {
     return {
         .port_number = static_cast<uint16_t>(port_number),
         .protocol_type = protocol_type,
@@ -126,7 +127,7 @@
               pref.value().FindIntKey(crostini::kPortNumberKey).value());
     EXPECT_EQ(static_cast<int>(key.protocol_type),
               pref.value().FindIntKey(crostini::kPortProtocolKey).value());
-    EXPECT_EQ(key.container_id, ContainerId(pref.value()));
+    EXPECT_EQ(key.container_id, guest_os::GuestId(pref.value()));
     EXPECT_EQ(label, *pref.value().FindStringKey(crostini::kPortLabelKey));
   }
 
@@ -186,9 +187,9 @@
     return success;
   }
 
-  ContainerId default_container_id_;
-  ContainerId other_container_id_;
-  ContainerId inactive_container_id_;
+  guest_os::GuestId default_container_id_;
+  guest_os::GuestId other_container_id_;
+  guest_os::GuestId inactive_container_id_;
 
   testing::NiceMock<MockPortObserver> mock_observer_;
 
@@ -433,7 +434,7 @@
 }
 
 TEST_F(CrostiniPortForwarderTest, DeactivateAllPorts) {
-  ContainerId container_id = default_container_id_;
+  guest_os::GuestId container_id = default_container_id_;
   std::vector<CrostiniPortForwarder::PortRuleKey> ports_to_add = {
       GetPortKey(5000, Protocol::TCP, container_id),
       GetPortKey(5000, Protocol::UDP, container_id),
@@ -464,7 +465,7 @@
 }
 
 TEST_F(CrostiniPortForwarderTest, RemoveAllPorts) {
-  ContainerId container_id = default_container_id_;
+  guest_os::GuestId container_id = default_container_id_;
   std::vector<CrostiniPortForwarder::PortRuleKey> ports_to_add = {
       GetPortKey(5000, Protocol::TCP, container_id),
       GetPortKey(5000, Protocol::UDP, container_id),
@@ -497,7 +498,7 @@
 }
 
 TEST_F(CrostiniPortForwarderTest, GetActivePorts) {
-  ContainerId container_id = default_container_id_;
+  guest_os::GuestId container_id = default_container_id_;
   std::vector<CrostiniPortForwarder::PortRuleKey> ports_to_add = {
       GetPortKey(5000, Protocol::TCP, container_id),
       GetPortKey(5000, Protocol::UDP, container_id),
diff --git a/chrome/browser/ash/crostini/crostini_sshfs.cc b/chrome/browser/ash/crostini/crostini_sshfs.cc
index 2871348fa..6844ee0 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs.cc
+++ b/chrome/browser/ash/crostini/crostini_sshfs.cc
@@ -29,16 +29,16 @@
 
 CrostiniSshfs::~CrostiniSshfs() = default;
 
-void CrostiniSshfs::OnContainerShutdown(const ContainerId& container_id) {
+void CrostiniSshfs::OnContainerShutdown(const guest_os::GuestId& container_id) {
   container_shutdown_observer_.Reset();
   SetSshfsMounted(container_id, false);
 }
 
-bool CrostiniSshfs::IsSshfsMounted(const ContainerId& container) {
+bool CrostiniSshfs::IsSshfsMounted(const guest_os::GuestId& container) {
   return (sshfs_mounted_.count(container));
 }
 
-void CrostiniSshfs::SetSshfsMounted(const ContainerId& container,
+void CrostiniSshfs::SetSshfsMounted(const guest_os::GuestId& container,
                                     bool mounted) {
   if (mounted) {
     sshfs_mounted_.emplace(container);
@@ -47,7 +47,7 @@
   }
 }
 
-void CrostiniSshfs::UnmountCrostiniFiles(const ContainerId& container_id,
+void CrostiniSshfs::UnmountCrostiniFiles(const guest_os::GuestId& container_id,
                                          MountCrostiniFilesCallback callback) {
   // TODO(crbug/1197986): Unmounting should cancel an in-progress mount.
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -67,7 +67,7 @@
 }
 
 void CrostiniSshfs::OnRemoveSshfsCrostiniVolume(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     MountCrostiniFilesCallback callback,
     base::Time started,
     bool success) {
@@ -79,7 +79,7 @@
   std::move(callback).Run(success);
 }
 
-void CrostiniSshfs::MountCrostiniFiles(const ContainerId& container_id,
+void CrostiniSshfs::MountCrostiniFiles(const guest_os::GuestId& container_id,
                                        MountCrostiniFilesCallback callback,
                                        bool background) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -231,7 +231,7 @@
 }
 
 CrostiniSshfs::InProgressMount::InProgressMount(
-    const ContainerId& container,
+    const guest_os::GuestId& container,
     MountCrostiniFilesCallback callback,
     bool background)
     : container_id(container),
@@ -245,7 +245,7 @@
 CrostiniSshfs::InProgressMount::~InProgressMount() = default;
 
 CrostiniSshfs::PendingRequest::PendingRequest(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     MountCrostiniFilesCallback callback,
     bool background)
     : container_id(container_id),
diff --git a/chrome/browser/ash/crostini/crostini_sshfs.h b/chrome/browser/ash/crostini/crostini_sshfs.h
index 9fb8b3a9..6279d88 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs.h
+++ b/chrome/browser/ash/crostini/crostini_sshfs.h
@@ -33,24 +33,24 @@
   // mounted. If this is something running in the background set background to
   // true, if failures are user-visible set it to false. If you're setting
   // base::DoNothing as the callback then background should be true.
-  void MountCrostiniFiles(const ContainerId& container_id,
+  void MountCrostiniFiles(const guest_os::GuestId& container_id,
                           MountCrostiniFilesCallback callback,
                           bool background);
 
   // Unmounts the user's Crostini home directory. Must be called from the UI
   // thread.
-  void UnmountCrostiniFiles(const ContainerId& container_id,
+  void UnmountCrostiniFiles(const guest_os::GuestId& container_id,
                             MountCrostiniFilesCallback callback);
 
   // ContainerShutdownObserver.
-  void OnContainerShutdown(const ContainerId& container_id) override;
+  void OnContainerShutdown(const guest_os::GuestId& container_id) override;
 
   void OnMountEvent(
       chromeos::MountError error_code,
       const ash::disks::DiskMountManager::MountPointInfo& mount_info);
 
   // Returns true if sshfs is mounted for the specified container, else false.
-  bool IsSshfsMounted(const ContainerId& container);
+  bool IsSshfsMounted(const guest_os::GuestId& container);
 
   // Only public so unit tests can reference them without needing to FRIEND_TEST
   // every single test case.
@@ -69,10 +69,10 @@
   };
 
  private:
-  void SetSshfsMounted(const ContainerId& container, bool mounted);
+  void SetSshfsMounted(const guest_os::GuestId& container, bool mounted);
   void Finish(CrostiniSshfsResult result);
 
-  void OnRemoveSshfsCrostiniVolume(const ContainerId& container_id,
+  void OnRemoveSshfsCrostiniVolume(const guest_os::GuestId& container_id,
                                    MountCrostiniFilesCallback callback,
                                    base::Time started,
                                    bool success);
@@ -84,12 +84,12 @@
 
   struct InProgressMount {
     std::string source_path;
-    ContainerId container_id;
+    guest_os::GuestId container_id;
     base::FilePath container_homedir;
     MountCrostiniFilesCallback callback;
     base::Time started;
     bool background;
-    InProgressMount(const ContainerId& container,
+    InProgressMount(const guest_os::GuestId& container,
                     MountCrostiniFilesCallback callback,
                     bool background);
     InProgressMount(InProgressMount&& other) noexcept;
@@ -97,10 +97,10 @@
     ~InProgressMount();
   };
   struct PendingRequest {
-    ContainerId container_id;
+    guest_os::GuestId container_id;
     MountCrostiniFilesCallback callback;
     bool background;
-    PendingRequest(const ContainerId& container_id,
+    PendingRequest(const guest_os::GuestId& container_id,
                    MountCrostiniFilesCallback callback,
                    bool background);
     PendingRequest(PendingRequest&& other) noexcept;
@@ -117,7 +117,7 @@
 
   std::unique_ptr<InProgressMount> in_progress_mount_;
 
-  std::set<ContainerId> sshfs_mounted_;
+  std::set<guest_os::GuestId> sshfs_mounted_;
   std::queue<PendingRequest> pending_requests_;
 
   // Note: This should remain the last member so it'll be destroyed and
diff --git a/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc b/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
index ec14b228..ec1aecee 100644
--- a/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_sshfs_unittest.cc
@@ -145,7 +145,7 @@
             Invoke(this, &CrostiniSshfsHelperTest::NotifyMountEvent));
   }
 
-  void SetContainerRunning(ContainerId container) {
+  void SetContainerRunning(guest_os::GuestId container) {
     auto* manager = CrostiniManager::GetForProfile(profile());
     ContainerInfo info(container.container_name, "username", "homedir",
                        "1.2.3.4");
@@ -206,7 +206,7 @@
 }
 
 TEST_F(CrostiniSshfsHelperTest, OnlyDefaultContainerSupported) {
-  auto not_default = ContainerId("vm_name", "container_name");
+  auto not_default = guest_os::GuestId("vm_name", "container_name");
   SetContainerRunning(not_default);
   EXPECT_CALL(*disk_manager_, MountPath).Times(0);
 
@@ -224,7 +224,7 @@
 }
 
 TEST_F(CrostiniSshfsHelperTest, RecordBackgroundMetricIfBackground) {
-  auto not_default = ContainerId("vm_name", "container_name");
+  auto not_default = guest_os::GuestId("vm_name", "container_name");
   SetContainerRunning(not_default);
   EXPECT_CALL(*disk_manager_, MountPath).Times(0);
 
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc
index 20665c3..df8ebcb4 100644
--- a/chrome/browser/ash/crostini/crostini_terminal.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -165,7 +165,7 @@
 
 GURL GenerateTerminalURL(Profile* profile,
                          const std::string& settings_profile,
-                         const ContainerId& container_id,
+                         const guest_os::GuestId& container_id,
                          const std::string& cwd,
                          const std::vector<std::string>& terminal_args) {
   auto escape = [](std::string param) {
@@ -205,7 +205,7 @@
 
 void LaunchTerminal(Profile* profile,
                     int64_t display_id,
-                    const ContainerId& container_id,
+                    const guest_os::GuestId& container_id,
                     const std::string& cwd,
                     const std::vector<std::string>& terminal_args) {
   GURL url = GenerateTerminalURL(profile, /*settings_profile=*/std::string(),
@@ -256,7 +256,7 @@
   }
 
   // Look for vm_name and container_name in intent->extras.
-  ContainerId container_id = DefaultContainerId();
+  guest_os::GuestId container_id = DefaultContainerId();
   std::string settings_profile;
   if (intent && intent->extras.has_value()) {
     for (const auto& extra : intent->extras.value()) {
@@ -476,7 +476,7 @@
 }
 
 std::string ShortcutIdFromContainerId(Profile* profile,
-                                      const crostini::ContainerId& id) {
+                                      const guest_os::GuestId& id) {
   base::Value::Dict dict = id.ToDictValue();
   dict.Set(kShortcutKey, base::Value(kShortcutValueTerminal));
 
diff --git a/chrome/browser/ash/crostini/crostini_terminal.h b/chrome/browser/ash/crostini/crostini_terminal.h
index 9fd81d0..1f826fc 100644
--- a/chrome/browser/ash/crostini/crostini_terminal.h
+++ b/chrome/browser/ash/crostini/crostini_terminal.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/display/types/display_constants.h"
@@ -113,18 +114,20 @@
 const std::string& GetTerminalHomeUrl();
 
 // Generate URL to launch terminal.
-GURL GenerateTerminalURL(Profile* profile,
-                         const std::string& setings_profile,
-                         const ContainerId& container_id = DefaultContainerId(),
-                         const std::string& cwd = "",
-                         const std::vector<std::string>& terminal_args = {});
+GURL GenerateTerminalURL(
+    Profile* profile,
+    const std::string& setings_profile,
+    const guest_os::GuestId& container_id = DefaultContainerId(),
+    const std::string& cwd = "",
+    const std::vector<std::string>& terminal_args = {});
 
 // Launches the terminal tabbed app.
-void LaunchTerminal(Profile* profile,
-                    int64_t display_id = display::kInvalidDisplayId,
-                    const ContainerId& container_id = DefaultContainerId(),
-                    const std::string& cwd = "",
-                    const std::vector<std::string>& terminal_args = {});
+void LaunchTerminal(
+    Profile* profile,
+    int64_t display_id = display::kInvalidDisplayId,
+    const guest_os::GuestId& container_id = DefaultContainerId(),
+    const std::string& cwd = "",
+    const std::vector<std::string>& terminal_args = {});
 
 void LaunchTerminalHome(Profile* profile, int64_t display_id);
 
@@ -158,7 +161,7 @@
 
 // Menu shortcut ID for Linux container.
 std::string ShortcutIdFromContainerId(Profile* profile,
-                                      const crostini::ContainerId& id);
+                                      const guest_os::GuestId& id);
 
 // Returns list of SSH connections {<profile-id>, <description>}.
 std::vector<std::pair<std::string, std::string>> GetSSHConnections(
diff --git a/chrome/browser/ash/crostini/crostini_terminal_provider.cc b/chrome/browser/ash/crostini/crostini_terminal_provider.cc
index 6c56024..bb5a5ab 100644
--- a/chrome/browser/ash/crostini/crostini_terminal_provider.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal_provider.cc
@@ -9,7 +9,8 @@
 
 namespace crostini {
 
-CrostiniTerminalProvider::CrostiniTerminalProvider(ContainerId container_id)
+CrostiniTerminalProvider::CrostiniTerminalProvider(
+    guest_os::GuestId container_id)
     : container_id_(container_id) {}
 CrostiniTerminalProvider::~CrostiniTerminalProvider() = default;
 
@@ -21,7 +22,7 @@
       {container_id_.vm_name, ":", container_id_.container_name});
 }
 
-absl::optional<crostini::ContainerId>
+absl::optional<guest_os::GuestId>
 CrostiniTerminalProvider::CrostiniContainerId() {
   return container_id_;
 }
diff --git a/chrome/browser/ash/crostini/crostini_terminal_provider.h b/chrome/browser/ash/crostini/crostini_terminal_provider.h
index add0295..6f5b9f36 100644
--- a/chrome/browser/ash/crostini/crostini_terminal_provider.h
+++ b/chrome/browser/ash/crostini/crostini_terminal_provider.h
@@ -6,13 +6,14 @@
 #define CHROME_BROWSER_ASH_CROSTINI_CROSTINI_TERMINAL_PROVIDER_H_
 
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h"
 
 namespace crostini {
 
 class CrostiniTerminalProvider : public guest_os::GuestOsTerminalProvider {
  public:
-  explicit CrostiniTerminalProvider(ContainerId container_id_);
+  explicit CrostiniTerminalProvider(guest_os::GuestId container_id_);
   ~CrostiniTerminalProvider() override;
 
   std::string Label() override;
@@ -20,10 +21,10 @@
   // TODO(b/233287586): While we're migrating some Crostini-specific code still
   // needs a ContainerId. Eventually this should always be nullopt and then
   // removed.
-  absl::optional<crostini::ContainerId> CrostiniContainerId() override;
+  absl::optional<guest_os::GuestId> CrostiniContainerId() override;
 
  private:
-  ContainerId container_id_;
+  guest_os::GuestId container_id_;
 };
 
 }  // namespace crostini
diff --git a/chrome/browser/ash/crostini/crostini_terminal_provider_unittest.cc b/chrome/browser/ash/crostini/crostini_terminal_provider_unittest.cc
index 0c0719e3..bffc75a 100644
--- a/chrome/browser/ash/crostini/crostini_terminal_provider_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal_provider_unittest.cc
@@ -12,10 +12,10 @@
 class CrostiniTerminalProviderTest : public testing::Test {};
 
 TEST_F(CrostiniTerminalProviderTest, Label) {
-  ContainerId id1("vm_name", "container");
+  guest_os::GuestId id1("vm_name", "container");
   ASSERT_EQ(CrostiniTerminalProvider(id1).Label(), "vm_name:container");
 
-  ContainerId id2("termina", "notpenguin");
+  guest_os::GuestId id2("termina", "notpenguin");
   ASSERT_EQ(CrostiniTerminalProvider(id2).Label(), "notpenguin");
 
   // Leave the VM name off the label if it's the default VM.
diff --git a/chrome/browser/ash/crostini/crostini_terminal_unittest.cc b/chrome/browser/ash/crostini/crostini_terminal_unittest.cc
index 79a383d..e6ff59b 100644
--- a/chrome/browser/ash/crostini/crostini_terminal_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/values.h"
 #include "chrome/browser/ash/crostini/crostini_pref_names.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -28,7 +29,7 @@
             "&args[]=--target_container%3Dpenguin"
             "&args[]=--owner_id%3Dtest");
   EXPECT_EQ(GenerateTerminalURL(&profile, "red",
-                                ContainerId("test-vm", "test-container"),
+                                guest_os::GuestId("test-vm", "test-container"),
                                 "/home/user", {"arg1"}),
             "chrome-untrusted://terminal/html/terminal.html"
             "?command=vmshell"
@@ -48,7 +49,7 @@
 TEST_F(CrostiniTerminalTest, ShortcutIdFromContainerId) {
   content::BrowserTaskEnvironment task_environment;
   TestingProfile profile;
-  ContainerId id("test-vm", "test-container");
+  guest_os::GuestId id("test-vm", "test-container");
   EXPECT_EQ(ShortcutIdFromContainerId(&profile, id),
             R"({"container_name":"test-container","shortcut":"terminal",)"
             R"("vm_name":"test-vm"})");
diff --git a/chrome/browser/ash/crostini/crostini_upgrader.cc b/chrome/browser/ash/crostini/crostini_upgrader.cc
index 13a3cab6..3029978e 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader.cc
+++ b/chrome/browser/ash/crostini/crostini_upgrader.cc
@@ -196,7 +196,7 @@
 }
 
 void CrostiniUpgrader::Backup(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool show_file_chooser,
     base::WeakPtr<content::WebContents> web_contents) {
   if (show_file_chooser) {
@@ -215,7 +215,7 @@
 }
 
 void CrostiniUpgrader::OnBackupPathChecked(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::WeakPtr<content::WebContents> web_contents,
     base::FilePath path,
     bool path_exists) {
@@ -306,7 +306,7 @@
   }
 }
 
-void CrostiniUpgrader::Upgrade(const ContainerId& container_id) {
+void CrostiniUpgrader::Upgrade(const guest_os::GuestId& container_id) {
   container_id_ = container_id;
 
   if (!current_log_file_.has_value()) {
@@ -358,7 +358,7 @@
 }
 
 void CrostiniUpgrader::Restore(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::WeakPtr<content::WebContents> web_contents) {
   if (!backup_path_.has_value()) {
     CrostiniExportImport::GetForProfile(profile_)->ImportContainer(
@@ -374,7 +374,7 @@
 }
 
 void CrostiniUpgrader::OnRestorePathChecked(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     base::WeakPtr<content::WebContents> web_contents,
     base::FilePath path,
     bool path_exists) {
@@ -429,7 +429,7 @@
 }
 
 void CrostiniUpgrader::OnUpgradeContainerProgress(
-    const ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     UpgradeContainerProgressStatus status,
     const std::vector<std::string>& messages) {
   if (container_id != container_id_) {
diff --git a/chrome/browser/ash/crostini/crostini_upgrader.h b/chrome/browser/ash/crostini/crostini_upgrader.h
index 0ae0a3f..f43e059 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader.h
+++ b/chrome/browser/ash/crostini/crostini_upgrader.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/ash/crostini/crostini_export_import_status_tracker.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -39,19 +40,19 @@
   void AddObserver(CrostiniUpgraderUIObserver* observer) override;
   void RemoveObserver(CrostiniUpgraderUIObserver* observer) override;
   void PageOpened() override;
-  void Backup(const ContainerId& container_id,
+  void Backup(const guest_os::GuestId& container_id,
               bool show_file_chooser,
               base::WeakPtr<content::WebContents> web_contents) override;
   void StartPrechecks() override;
-  void Upgrade(const ContainerId& container_id) override;
-  void Restore(const ContainerId& container_id,
+  void Upgrade(const guest_os::GuestId& container_id) override;
+  void Restore(const guest_os::GuestId& container_id,
                base::WeakPtr<content::WebContents> web_contents) override;
   void Cancel() override;
   void CancelBeforeStart() override;
 
   // CrostiniManager::UpgradeContainerProgressObserver:
   void OnUpgradeContainerProgress(
-      const ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       UpgradeContainerProgressStatus status,
       const std::vector<std::string>& messages) override;
 
@@ -68,7 +69,7 @@
   // `log_sequence_`, which allows blocking operations.
   void WriteLogMessages(std::vector<std::string> messages);
 
-  void OnBackupPathChecked(const ContainerId& container_id,
+  void OnBackupPathChecked(const guest_os::GuestId& container_id,
                            base::WeakPtr<content::WebContents> web_contents,
                            base::FilePath path,
                            bool path_exists);
@@ -81,7 +82,7 @@
   void OnBackupProgress(int progress_percent);
   void OnUpgrade(CrostiniResult result);
   void DoPrechecks();
-  void OnRestorePathChecked(const ContainerId& container_id,
+  void OnRestorePathChecked(const guest_os::GuestId& container_id,
                             base::WeakPtr<content::WebContents> web_contents,
                             base::FilePath path,
                             bool path_exists);
@@ -111,7 +112,7 @@
   friend class StatusTracker;
 
   Profile* profile_;
-  ContainerId container_id_;
+  guest_os::GuestId container_id_;
   base::ObserverList<CrostiniUpgraderUIObserver>::Unchecked upgrader_observers_;
 
   base::OnceClosure prechecks_callback_;
diff --git a/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h b/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
index 3f2a496..7948d37 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
+++ b/chrome/browser/ash/crostini/crostini_upgrader_ui_delegate.h
@@ -18,9 +18,11 @@
 class WebContents;
 }  // namespace content
 
-namespace crostini {
+namespace guest_os {
+struct GuestId;
+}
 
-struct ContainerId;
+namespace crostini {
 
 class CrostiniUpgraderUIObserver {
  public:
@@ -56,17 +58,17 @@
   // Back up the current container before upgrading. If |show_file_chooser|
   // is true, the user will be able to select the backup location via a file
   // chooser.
-  virtual void Backup(const ContainerId& container_id,
+  virtual void Backup(const guest_os::GuestId& container_id,
                       bool show_file_chooser,
                       base::WeakPtr<content::WebContents> web_contents) = 0;
 
   virtual void StartPrechecks() = 0;
 
   // Start the upgrade.
-  virtual void Upgrade(const ContainerId& container_id) = 0;
+  virtual void Upgrade(const guest_os::GuestId& container_id) = 0;
 
   // Restore the container to the backed up state if an upgrade has failed.
-  virtual void Restore(const ContainerId& container_id,
+  virtual void Restore(const guest_os::GuestId& container_id,
                        base::WeakPtr<content::WebContents> web_contents) = 0;
 
   // Cancel the ongoing upgrade.
diff --git a/chrome/browser/ash/crostini/crostini_util.cc b/chrome/browser/ash/crostini/crostini_util.cc
index 56677d4..cc8a1df 100644
--- a/chrome/browser/ash/crostini/crostini_util.cc
+++ b/chrome/browser/ash/crostini/crostini_util.cc
@@ -111,8 +111,8 @@
         "failed to share paths to launch " + app_id + ":" + failure_reason,
         CrostiniResult::SHARE_PATHS_FAILED);
   }
-  const crostini::ContainerId container_id(registration.VmName(),
-                                           registration.ContainerName());
+  const guest_os::GuestId container_id(registration.VmName(),
+                                       registration.ContainerName());
   crostini::CrostiniManager::GetForProfile(profile)->LaunchContainerApplication(
       container_id, registration.DesktopFileId(), args, registration.IsScaled(),
       base::BindOnce(OnApplicationLaunched, app_id, std::move(callback),
@@ -179,51 +179,6 @@
 
 }  // namespace
 
-ContainerId::ContainerId(std::string vm_name,
-                         std::string container_name) noexcept
-    : vm_name(std::move(vm_name)), container_name(std::move(container_name)) {}
-
-ContainerId::ContainerId(const base::Value& value) noexcept {
-  const base::Value::Dict* dict = value.GetIfDict();
-  const std::string* vm = nullptr;
-  const std::string* container = nullptr;
-  if (dict != nullptr) {
-    vm = dict->FindString(prefs::kVmKey);
-    container = dict->FindString(prefs::kContainerKey);
-  }
-  vm_name = vm ? *vm : "";
-  container_name = container ? *container : "";
-}
-
-base::flat_map<std::string, std::string> ContainerId::ToMap() const {
-  base::flat_map<std::string, std::string> extras;
-  extras[prefs::kVmKey] = vm_name;
-  extras[prefs::kContainerKey] = container_name;
-  return extras;
-}
-
-base::Value::Dict ContainerId::ToDictValue() const {
-  base::Value::Dict dict;
-  dict.Set(prefs::kVmKey, vm_name);
-  dict.Set(prefs::kContainerKey, container_name);
-  return dict;
-}
-
-bool operator<(const ContainerId& lhs, const ContainerId& rhs) noexcept {
-  const auto result = lhs.vm_name.compare(rhs.vm_name);
-  return result < 0 || (result == 0 && lhs.container_name < rhs.container_name);
-}
-
-bool operator==(const ContainerId& lhs, const ContainerId& rhs) noexcept {
-  return lhs.vm_name == rhs.vm_name && lhs.container_name == rhs.container_name;
-}
-
-std::ostream& operator<<(std::ostream& ostream,
-                         const ContainerId& container_id) {
-  return ostream << "(vm: \"" << container_id.vm_name << "\" container: \""
-                 << container_id.container_name << "\")";
-}
-
 bool IsUninstallable(Profile* profile, const std::string& app_id) {
   if (!CrostiniFeatures::Get()->IsEnabled(profile)) {
     return false;
@@ -274,7 +229,7 @@
     Profile* profile,
     const std::string& app_id,
     guest_os::GuestOsRegistryService::Registration registration,
-    const ContainerId container_id,
+    const guest_os::GuestId container_id,
     int64_t display_id,
     const std::vector<LaunchArg>& args,
     CrostiniSuccessCallback callback) {
@@ -341,8 +296,8 @@
     return std::move(callback).Run(
         false, "LaunchCrostiniApp called with an unknown app_id: " + app_id);
   }
-  ContainerId container_id(registration->VmName(),
-                           registration->ContainerName());
+  guest_os::GuestId container_id(registration->VmName(),
+                                 registration->ContainerName());
 
   if (crostini_manager->IsUncleanStartup()) {
     VLOG(1) << "Unclean startup for " << container_id
@@ -407,7 +362,7 @@
 namespace {
 
 bool MatchContainerDict(const base::Value& dict,
-                        const ContainerId& container_id) {
+                        const guest_os::GuestId& container_id) {
   const std::string* vm_name = dict.FindStringKey(prefs::kVmKey);
   const std::string* container_name = dict.FindStringKey(prefs::kContainerKey);
   return (vm_name && *vm_name == container_id.vm_name) &&
@@ -419,10 +374,10 @@
 void RemoveDuplicateContainerEntries(PrefService* prefs) {
   ListPrefUpdate updater(prefs, crostini::prefs::kCrostiniContainers);
 
-  std::set<ContainerId> seen_containers;
+  std::set<guest_os::GuestId> seen_containers;
   auto& containers = updater->GetList();
   for (auto it = containers.begin(); it != containers.end();) {
-    ContainerId containerId(*it);
+    guest_os::GuestId containerId(*it);
     if (seen_containers.find(containerId) == seen_containers.end()) {
       seen_containers.insert(containerId);
       it++;
@@ -432,14 +387,14 @@
   }
 }
 
-std::vector<ContainerId> GetContainers(Profile* profile) {
-  std::vector<ContainerId> result;
+std::vector<guest_os::GuestId> GetContainers(Profile* profile) {
+  std::vector<guest_os::GuestId> result;
   const base::Value::List& container_list =
       profile->GetPrefs()
           ->GetList(crostini::prefs::kCrostiniContainers)
           ->GetList();
   for (const auto& container : container_list) {
-    crostini::ContainerId id(container);
+    guest_os::GuestId id(container);
     if (!id.vm_name.empty() && !id.container_name.empty()) {
       result.push_back(std::move(id));
     }
@@ -448,7 +403,7 @@
 }
 
 void AddNewLxdContainerToPrefs(Profile* profile,
-                               const ContainerId& container_id) {
+                               const guest_os::GuestId& container_id) {
   ListPrefUpdate updater(profile->GetPrefs(),
                          crostini::prefs::kCrostiniContainers);
   auto it = std::find_if(
@@ -469,7 +424,7 @@
 }
 
 void RemoveLxdContainerFromPrefs(Profile* profile,
-                                 const ContainerId& container_id) {
+                                 const guest_os::GuestId& container_id) {
   auto* pref_service = profile->GetPrefs();
   ListPrefUpdate updater(pref_service, crostini::prefs::kCrostiniContainers);
   updater->EraseListIter(
@@ -487,7 +442,7 @@
 }
 
 const base::Value* GetContainerPrefValue(Profile* profile,
-                                         const ContainerId& container_id,
+                                         const guest_os::GuestId& container_id,
                                          const std::string& key) {
   const base::Value* containers =
       profile->GetPrefs()->GetList(crostini::prefs::kCrostiniContainers);
@@ -502,7 +457,7 @@
 }
 
 void UpdateContainerPref(Profile* profile,
-                         const ContainerId& container_id,
+                         const guest_os::GuestId& container_id,
                          const std::string& key,
                          base::Value value) {
   ListPrefUpdate updater(profile->GetPrefs(),
@@ -516,7 +471,7 @@
 }
 
 SkColor GetContainerBadgeColor(Profile* profile,
-                               const ContainerId& container_id) {
+                               const guest_os::GuestId& container_id) {
   const base::Value* badge_color_value =
       GetContainerPrefValue(profile, container_id, prefs::kContainerColorKey);
   if (badge_color_value) {
@@ -527,7 +482,7 @@
 }
 
 void SetContainerBadgeColor(Profile* profile,
-                            const ContainerId& container_id,
+                            const guest_os::GuestId& container_id,
                             SkColor badge_color) {
   UpdateContainerPref(profile, container_id, prefs::kContainerColorKey,
                       base::Value(static_cast<int>(badge_color)));
@@ -537,7 +492,7 @@
 }
 
 bool IsContainerVersionExpired(Profile* profile,
-                               const ContainerId& container_id) {
+                               const guest_os::GuestId& container_id) {
   auto* value = GetContainerPrefValue(profile, container_id,
                                       prefs::kContainerOsVersionKey);
   if (!value)
@@ -548,7 +503,7 @@
 }
 
 bool ShouldWarnAboutExpiredVersion(Profile* profile,
-                                   const ContainerId& container_id) {
+                                   const guest_os::GuestId& container_id) {
   if (!CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(profile)) {
     return false;
   }
@@ -584,8 +539,8 @@
   }
 }
 
-const ContainerId& DefaultContainerId() {
-  static const base::NoDestructor<ContainerId> container_id(
+const guest_os::GuestId& DefaultContainerId() {
+  static const base::NoDestructor<guest_os::GuestId> container_id(
       kCrostiniDefaultVmName, kCrostiniDefaultContainerName);
   return *container_id;
 }
@@ -626,14 +581,14 @@
   }
 }
 
-bool ShouldStopVm(Profile* profile, const ContainerId& container_id) {
+bool ShouldStopVm(Profile* profile, const guest_os::GuestId& container_id) {
   bool is_last_container = true;
   base::Value::ConstListView containers =
       profile->GetPrefs()
           ->GetList(prefs::kCrostiniContainers)
           ->GetListDeprecated();
   for (const auto& dict : containers) {
-    ContainerId container(dict);
+    guest_os::GuestId container(dict);
     if (container.container_name != container_id.container_name &&
         container.vm_name == container_id.vm_name) {
       if (CrostiniManager::GetForProfile(profile)->GetContainerInfo(
diff --git a/chrome/browser/ash/crostini/crostini_util.h b/chrome/browser/ash/crostini/crostini_util.h
index b6909f7..8cbfcb1 100644
--- a/chrome/browser/ash/crostini/crostini_util.h
+++ b/chrome/browser/ash/crostini/crostini_util.h
@@ -14,6 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/values.h"
 #include "chrome/browser/ash/crostini/crostini_simple_types.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "components/services/app_service/public/mojom/types.mojom-forward.h"
 #include "storage/browser/file_system/file_system_url.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
@@ -66,28 +67,6 @@
 
 struct LinuxPackageInfo;
 
-// A unique identifier for our containers.
-struct ContainerId {
-  ContainerId(std::string vm_name, std::string container_name) noexcept;
-  explicit ContainerId(const base::Value&) noexcept;
-
-  base::flat_map<std::string, std::string> ToMap() const;
-  base::Value::Dict ToDictValue() const;
-
-  std::string vm_name;
-  std::string container_name;
-};
-
-bool operator<(const ContainerId& lhs, const ContainerId& rhs) noexcept;
-bool operator==(const ContainerId& lhs, const ContainerId& rhs) noexcept;
-inline bool operator!=(const ContainerId& lhs,
-                       const ContainerId& rhs) noexcept {
-  return !(lhs == rhs);
-}
-
-std::ostream& operator<<(std::ostream& ostream,
-                         const ContainerId& container_id);
-
 // Checks if user profile is able to a crostini app with a given app_id.
 bool IsUninstallable(Profile* profile, const std::string& app_id);
 
@@ -187,16 +166,16 @@
 void RemoveDuplicateContainerEntries(PrefService* prefs);
 
 // Returns a list of all containers in prefs.
-std::vector<ContainerId> GetContainers(Profile* profile);
+std::vector<guest_os::GuestId> GetContainers(Profile* profile);
 
 // Add a newly created LXD container to the kCrostiniContainers pref
 void AddNewLxdContainerToPrefs(Profile* profile,
-                               const ContainerId& container_id);
+                               const guest_os::GuestId& container_id);
 
 // Remove a newly deleted LXD container from the kCrostiniContainers pref, and
 // deregister its apps and mime types.
 void RemoveLxdContainerFromPrefs(Profile* profile,
-                                 const ContainerId& container_id);
+                                 const guest_os::GuestId& container_id);
 
 // Returns a string to be displayed in a notification with the estimated time
 // left for an operation to run which started and time |start| and is current
@@ -205,29 +184,29 @@
 
 // Returns a pref value stored for a specific container.
 const base::Value* GetContainerPrefValue(Profile* profile,
-                                         const ContainerId& container_id,
+                                         const guest_os::GuestId& container_id,
                                          const std::string& key);
 
 // Sets a pref value for a specific container.
 void UpdateContainerPref(Profile* profile,
-                         const ContainerId& container_id,
+                         const guest_os::GuestId& container_id,
                          const std::string& key,
                          base::Value value);
 
 SkColor GetContainerBadgeColor(Profile* profile,
-                               const ContainerId& container_id);
+                               const guest_os::GuestId& container_id);
 
 void SetContainerBadgeColor(Profile* profile,
-                            const ContainerId& container_id,
+                            const guest_os::GuestId& container_id,
                             SkColor badge_color);
 
 bool IsContainerVersionExpired(Profile* profile,
-                               const ContainerId& container_id);
+                               const guest_os::GuestId& container_id);
 
 bool ShouldWarnAboutExpiredVersion(Profile* profile,
-                                   const ContainerId& container_id);
+                                   const guest_os::GuestId& container_id);
 
-const ContainerId& DefaultContainerId();
+const guest_os::GuestId& DefaultContainerId();
 
 bool IsCrostiniWindow(const aura::Window* window);
 
@@ -237,7 +216,7 @@
 
 // Tests whether or not the specified Container is the last one running on it's
 // VM. Returns true if the VM should be stopped.
-bool ShouldStopVm(Profile* profile, const ContainerId& container_id);
+bool ShouldStopVm(Profile* profile, const guest_os::GuestId& container_id);
 
 }  // namespace crostini
 
diff --git a/chrome/browser/ash/crostini/crostini_util_unittest.cc b/chrome/browser/ash/crostini/crostini_util_unittest.cc
index 80a1a3b..ce6856c 100644
--- a/chrome/browser/ash/crostini/crostini_util_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_util_unittest.cc
@@ -110,28 +110,6 @@
   BrowserProcessPlatformPartTestApi browser_part_;
 };
 
-TEST_F(CrostiniUtilTest, ContainerIdEquality) {
-  auto container1 = ContainerId{"test1", "test2"};
-  auto container2 = ContainerId{"test1", "test2"};
-  auto container3 = ContainerId{"test2", "test1"};
-
-  ASSERT_TRUE(container1 == container2);
-  ASSERT_FALSE(container1 == container3);
-  ASSERT_FALSE(container2 == container3);
-}
-
-TEST_F(CrostiniUtilTest, ContainerIdFromDictValue) {
-  base::Value dict(base::Value::Type::DICT);
-  dict.SetStringKey(prefs::kVmKey, "foo");
-  dict.SetStringKey(prefs::kContainerKey, "bar");
-  EXPECT_TRUE(ContainerId(dict) == ContainerId("foo", "bar"));
-}
-
-TEST_F(CrostiniUtilTest, ContainerIdFromNonDictValue) {
-  base::Value non_dict("not a dict value");
-  EXPECT_TRUE(ContainerId(non_dict) == ContainerId("", ""));
-}
-
 TEST_F(CrostiniUtilTest, LaunchCallbackRunsOnRestartError) {
   // Set Restart to fail.
   fake_concierge_client_->set_start_vm_response({});
@@ -148,17 +126,17 @@
 }
 
 TEST_F(CrostiniUtilTest, DuplicateContainerNamesInPrefsAreRemoved) {
-  ContainerId container1("test1", "test1");
+  guest_os::GuestId container1("test1", "test1");
   base::Value::Dict dictionary1 = container1.ToDictValue();
   dictionary1.Set(prefs::kContainerOsPrettyNameKey, "Test OS Name 1");
   dictionary1.Set(prefs::kContainerOsVersionKey, 1);
 
-  ContainerId container2("test1", "test2");
+  guest_os::GuestId container2("test1", "test2");
   base::Value::Dict dictionary2 = container2.ToDictValue();
   dictionary2.Set(prefs::kContainerOsPrettyNameKey, "Test OS Name 2");
   dictionary2.Set(prefs::kContainerOsVersionKey, 2);
 
-  ContainerId container3("test2", "test1");
+  guest_os::GuestId container3("test2", "test1");
   base::Value::Dict dictionary3 = container3.ToDictValue();
   dictionary3.Set(prefs::kContainerOsPrettyNameKey, "Test OS Name 3");
   dictionary3.Set(prefs::kContainerOsVersionKey, 3);
@@ -186,8 +164,8 @@
 
 TEST_F(CrostiniUtilTest, ShouldStopVm) {
   CrostiniManager* manager = CrostiniManager::GetForProfile(profile_.get());
-  ContainerId containera("apple", "banana");
-  ContainerId containerb("potato", "strawberry");
+  guest_os::GuestId containera("apple", "banana");
+  guest_os::GuestId containerb("potato", "strawberry");
   base::Value::List containers;
   containers.Append(containera.ToDictValue().Clone());
   containers.Append(containerb.ToDictValue().Clone());
@@ -210,8 +188,8 @@
 
 TEST_F(CrostiniUtilTest, ShouldNotStopVm) {
   CrostiniManager* manager = CrostiniManager::GetForProfile(profile_.get());
-  ContainerId containera("apple", "banana");
-  ContainerId containerb("apple", "strawberry");
+  guest_os::GuestId containera("apple", "banana");
+  guest_os::GuestId containerb("apple", "strawberry");
   base::Value::List containers;
   containers.Append(containera.ToDictValue().Clone());
   containers.Append(containerb.ToDictValue().Clone());
@@ -238,8 +216,8 @@
   ])");
   ASSERT_TRUE(pref.has_value());
   profile_->GetPrefs()->Set(prefs::kCrostiniContainers, std::move(*pref));
-  std::vector<ContainerId> expected = {ContainerId("vm1", "c1"),
-                                       ContainerId("vm2", "c2")};
+  std::vector<guest_os::GuestId> expected = {guest_os::GuestId("vm1", "c1"),
+                                             guest_os::GuestId("vm2", "c2")};
   EXPECT_EQ(GetContainers(profile_.get()), expected);
 }
 }  // namespace crostini
diff --git a/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc b/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
index 09d68e5a2..5559d641 100644
--- a/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
+++ b/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ash/crostini/crostini_terminal.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/exo/chrome_data_exchange_delegate.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/guest_os_mime_types_service.h"
 #include "chrome/browser/ash/guest_os/guest_os_mime_types_service_factory.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
@@ -137,7 +138,7 @@
     // kInvalidDisplayId will launch terminal on the current active display.
     crostini::LaunchTerminal(
         profile, display::kInvalidDisplayId,
-        crostini::ContainerId(request.vm_name(), request.container_name()),
+        guest_os::GuestId(request.vm_name(), request.container_name()),
         request.cwd(),
         std::vector<std::string>(request.params().begin(),
                                  request.params().end()));
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index 7dd01145..42928fe 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -73,6 +73,7 @@
 #include "chrome/browser/ash/file_manager/mount_test_util.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/ash/file_manager/volume_manager.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_mount_provider.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_service.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
@@ -1703,7 +1704,7 @@
 
   std::string DisplayName() override { return name_; }
   Profile* profile() override { return profile_; }
-  crostini::ContainerId ContainerId() override {
+  guest_os::GuestId GuestId() override {
     return crostini::DefaultContainerId();
   }
 
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc
index a1c95f9..a733e95 100644
--- a/chrome/browser/ash/file_manager/file_manager_jstest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc
@@ -7,8 +7,9 @@
 
 class FileManagerJsTest : public FileManagerJsTestBase {
  protected:
-  FileManagerJsTest() : FileManagerJsTestBase(
-      base::FilePath(FILE_PATH_LITERAL("ui/file_manager/file_manager"))) {}
+  FileManagerJsTest()
+      : FileManagerJsTestBase(
+            base::FilePath(FILE_PATH_LITERAL("file_manager"))) {}
 };
 
 // Tests that draw to canvases and test pixels need pixel output turned on.
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest_base.cc b/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
index 56d23d6..5c430466 100644
--- a/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
@@ -25,6 +25,7 @@
 #include "content/public/test/scoped_web_ui_controller_factory_registration.h"
 #include "net/base/filename_util.h"
 #include "services/network/public/mojom/content_security_policy.mojom.h"
+#include "ui/base/resource/resource_bundle.h"
 
 namespace {
 
@@ -34,133 +35,6 @@
   return executable_path.AppendASCII("gen");
 }
 
-// URLDataSource for the test URL chrome://file_manager_test/. It reads files
-// directly from repository source.
-class TestFilesDataSource : public content::URLDataSource {
- public:
-  TestFilesDataSource() {}
-
-  TestFilesDataSource(const TestFilesDataSource&) = delete;
-  TestFilesDataSource& operator=(const TestFilesDataSource&) = delete;
-
-  ~TestFilesDataSource() override {}
-
- private:
-  // This has to match TestResourceUrl()
-  std::string GetSource() override { return "file_manager_test"; }
-
-  void StartDataRequest(
-      const GURL& url,
-      const content::WebContents::Getter& wc_getter,
-      content::URLDataSource::GotDataCallback callback) override {
-    const std::string path = content::URLDataSource::URLToRequestPath(url);
-    base::ThreadPool::PostTask(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
-        base::BindOnce(&TestFilesDataSource::ReadFile, base::Unretained(this),
-                       path, std::move(callback)));
-  }
-
-  void ReadFile(const std::string& path,
-                content::URLDataSource::GotDataCallback callback) {
-    if (source_root_.empty()) {
-      CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root_));
-    }
-    if (gen_root_.empty()) {
-      CHECK(base::PathService::Get(base::DIR_EXE, &gen_root_));
-      gen_root_ = GetGenRoot();
-    }
-
-    std::string content;
-
-    base::FilePath src_file_path =
-        source_root_.Append(base::FilePath::FromUTF8Unsafe(path));
-    base::FilePath gen_file_path =
-        gen_root_.Append(base::FilePath::FromUTF8Unsafe(path));
-
-    // File manager sets up the embedded test server with a specific base path,
-    // and the server assumes all paths are relative to this path without
-    // checking for absolute URLs. Hence, absolute URLS are transformed to
-    // requests for <some_base_path>/chrome://resources/<path_to_resource>.
-    // Strip off the assumed base path and replace chrome://resources with
-    // ui/webui/resources in this case.
-    const char kResourcesUrl[] = "chrome://resources";
-    size_t url_pos = path.find(kResourcesUrl);
-    if (url_pos != std::string::npos) {
-      std::string new_path =
-          "ui/webui/resources" +
-          path.substr(url_pos + std::size(kResourcesUrl) - 1);
-      src_file_path =
-          source_root_.Append(base::FilePath::FromUTF8Unsafe(new_path));
-      gen_file_path =
-          gen_root_.Append(base::FilePath::FromUTF8Unsafe(new_path));
-    }
-
-    // Do some basic validation of the file extension.
-    CHECK(src_file_path.Extension() == ".html" ||
-          src_file_path.Extension() == ".js" ||
-          src_file_path.Extension() == ".css" ||
-          src_file_path.Extension() == ".svg")
-        << "chrome://file_manager_test/ only supports .html/.js/.css/.svg "
-           "extension files";
-
-    CHECK(base::PathExists(src_file_path) || base::PathExists(gen_file_path))
-        << src_file_path << " or: " << gen_file_path << " input path: " << path;
-    CHECK(base::ReadFileToString(gen_file_path, &content) ||
-          base::ReadFileToString(src_file_path, &content))
-        << src_file_path << " or: " << gen_file_path;
-
-    scoped_refptr<base::RefCountedString> response =
-        base::RefCountedString::TakeString(&content);
-    std::move(callback).Run(response.get());
-  }
-
-  bool ShouldServeMimeTypeAsContentTypeHeader() override { return true; }
-
-  // It currently only serves HTML/JS/CSS/SVG.
-  std::string GetMimeType(const std::string& path) override {
-    if (base::EndsWith(path, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
-      return "text/html";
-    }
-
-    if (base::EndsWith(path, ".css", base::CompareCase::INSENSITIVE_ASCII)) {
-      return "text/css";
-    }
-
-    if (base::EndsWith(path, ".js", base::CompareCase::INSENSITIVE_ASCII)) {
-      return "application/javascript";
-    }
-
-    if (base::EndsWith(path, ".svg", base::CompareCase::INSENSITIVE_ASCII)) {
-      return "image/svg+xml";
-    }
-
-    LOG(FATAL) << "unsupported file type: " << path;
-    return {};
-  }
-
-  std::string GetContentSecurityPolicy(
-      const network::mojom::CSPDirectiveName directive) override {
-    if (directive == network::mojom::CSPDirectiveName::ScriptSrc) {
-      // Add 'unsafe-inline' to CSP to allow the inline <script> in the
-      // generated HTML to run see js_test_gen_html.py.
-      return "script-src chrome://resources chrome://test 'self'  "
-             "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj "
-             "chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp "
-             "'unsafe-inline'; ";
-    } else if (directive ==
-                   network::mojom::CSPDirectiveName::RequireTrustedTypesFor ||
-               directive == network::mojom::CSPDirectiveName::TrustedTypes) {
-      return std::string();
-    }
-
-    return content::URLDataSource::GetContentSecurityPolicy(directive);
-  }
-
-  // Root of repository source, where files are served directly from.
-  base::FilePath source_root_;
-  base::FilePath gen_root_;
-};
-
 // WebUIProvider to attach the URLDataSource for the test URL during tests.
 // Used to start the unittest from a chrome:// URL which allows unittest files
 // (HTML/JS/CSS) to load other resources from WebUI URLs chrome://*.
@@ -176,21 +50,36 @@
 
   std::unique_ptr<content::WebUIController> NewWebUI(content::WebUI* web_ui,
                                                      const GURL& url) override {
-    auto* profile = Profile::FromWebUI(web_ui);
-    content::URLDataSource::Add(profile,
-                                std::make_unique<TestFilesDataSource>());
-    content::URLDataSource::Add(profile,
-                                std::make_unique<TestDataSource>("webui"));
-
     return std::make_unique<content::WebUIController>(web_ui);
   }
+
+  void DataSourceOverrides(content::WebUIDataSource* source) override {
+    // Add 'unsafe-inline' to CSP to allow the inline <script> in the
+    // generated HTML to run see js_test_gen_html.py.
+    source->OverrideContentSecurityPolicy(
+        network::mojom::CSPDirectiveName::ScriptSrc,
+        "script-src chrome://resources chrome://webui-test chrome://test "
+        "'self' chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj "
+        "chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp "
+        "'unsafe-inline'; ");
+
+    source->OverrideContentSecurityPolicy(
+        network::mojom::CSPDirectiveName::ScriptSrcElem,
+        "script-src chrome://resources chrome://webui-test chrome://test "
+        "'self' chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj "
+        "chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp "
+        "'unsafe-inline'; ");
+
+    // TODO(crbug.com/1098685): Trusted Type remaining WebUI.
+    source->DisableTrustedTypesCSP();
+  }
 };
 
 base::LazyInstance<TestWebUIProvider>::DestructorAtExit test_webui_provider_ =
     LAZY_INSTANCE_INITIALIZER;
 
 static const GURL TestResourceUrl() {
-  static GURL url(content::GetWebUIURLString("file_manager_test"));
+  static GURL url(content::GetWebUIURLString("webui-test"));
   return url;
 }
 
@@ -227,8 +116,7 @@
 }
 
 void FileManagerJsTestBase::RunTestURL(const std::string& file) {
-  RunTestImpl(
-      GURL("chrome://file_manager_test/" + base_path_.Append(file).value()));
+  RunTestImpl(GURL("chrome://webui-test/" + base_path_.Append(file).value()));
 }
 
 void FileManagerJsTestBase::RunTestImpl(const GURL& url) {
@@ -242,6 +130,12 @@
 void FileManagerJsTestBase::SetUpOnMainThread() {
   InProcessBrowserTest::SetUpOnMainThread();
 
+  base::FilePath pak_path;
+  ASSERT_TRUE(base::PathService::Get(base::DIR_MODULE, &pak_path));
+  pak_path = pak_path.AppendASCII("browser_tests.pak");
+  ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
+      pak_path, ui::kScaleFactorNone);
+
   webui_controller_factory_ =
       std::make_unique<TestChromeWebUIControllerFactory>();
   webui_controller_factory_registration_ =
diff --git a/chrome/browser/ash/file_manager/file_watcher.cc b/chrome/browser/ash/file_manager/file_watcher.cc
index 639ff3a..73b0d79 100644
--- a/chrome/browser/ash/file_manager/file_watcher.cc
+++ b/chrome/browser/ash/file_manager/file_watcher.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/common/task_util.h"
 
@@ -86,7 +87,7 @@
 
  private:
   // crostini::CrostiniFileChangeObserver overrides
-  void OnCrostiniFileChanged(const crostini::ContainerId& container_id,
+  void OnCrostiniFileChanged(const guest_os::GuestId& container_id,
                              const base::FilePath& path) override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     if (container_id != container_id_) {
@@ -100,7 +101,7 @@
   crostini::CrostiniManager* crostini_manager_;
   const base::FilePath crostini_mount_;
   const base::FilePath crostini_path_;
-  const crostini::ContainerId container_id_;
+  const guest_os::GuestId container_id_;
   base::FilePathWatcher::Callback file_watcher_callback_;
 };
 
diff --git a/chrome/browser/ash/file_manager/image_loader_jstest.cc b/chrome/browser/ash/file_manager/image_loader_jstest.cc
index 219df76..c3b0c08 100644
--- a/chrome/browser/ash/file_manager/image_loader_jstest.cc
+++ b/chrome/browser/ash/file_manager/image_loader_jstest.cc
@@ -9,8 +9,9 @@
 
 class ImageLoaderJsTest : public FileManagerJsTestBase {
  protected:
-  ImageLoaderJsTest() : FileManagerJsTestBase(
-      base::FilePath(FILE_PATH_LITERAL("ui/file_manager/image_loader"))) {}
+  ImageLoaderJsTest()
+      : FileManagerJsTestBase(
+            base::FilePath(FILE_PATH_LITERAL("image_loader"))) {}
 
   void SetUpCommandLine(base::CommandLine* command_lin) override {
     // Until Files SWA is fully launched Image Loader imports using
diff --git a/chrome/browser/ash/file_manager/path_util.cc b/chrome/browser/ash/file_manager/path_util.cc
index 8762e05..45ea82d 100644
--- a/chrome/browser/ash/file_manager/path_util.cc
+++ b/chrome/browser/ash/file_manager/path_util.cc
@@ -387,7 +387,7 @@
 }
 
 std::string GetGuestOsMountPointName(Profile* profile,
-                                     crostini::ContainerId id) {
+                                     const guest_os::GuestId& id) {
   return base::JoinString(
       {"guestos", ash::ProfileHelper::GetUserIdHashFromProfile(profile),
        base::EscapeAllExceptUnreserved(id.vm_name),
diff --git a/chrome/browser/ash/file_manager/path_util.h b/chrome/browser/ash/file_manager/path_util.h
index afa501c..d9b5213 100644
--- a/chrome/browser/ash/file_manager/path_util.h
+++ b/chrome/browser/ash/file_manager/path_util.h
@@ -10,7 +10,7 @@
 
 #include "base/callback.h"
 #include "base/files/file_path.h"
-#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "storage/browser/file_system/file_system_url.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -110,7 +110,7 @@
 
 // The canonical mount point name for the Guest OS `id`.
 std::string GetGuestOsMountPointName(Profile* profile,
-                                     crostini::ContainerId id);
+                                     const guest_os::GuestId& id);
 
 // The actual directory the crostini "Linux files" folder is mounted.
 base::FilePath GetCrostiniMountDirectory(Profile* profile);
diff --git a/chrome/browser/ash/file_manager/volume_manager.cc b/chrome/browser/ash/file_manager/volume_manager.cc
index 17fc537..f3c3e1f 100644
--- a/chrome/browser/ash/file_manager/volume_manager.cc
+++ b/chrome/browser/ash/file_manager/volume_manager.cc
@@ -44,6 +44,7 @@
 #include "chrome/browser/ash/file_manager/volume_manager_factory.h"
 #include "chrome/browser/ash/file_manager/volume_manager_observer.h"
 #include "chrome/browser/ash/file_system_provider/provided_file_system_info.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
diff --git a/chrome/browser/ash/guest_os/guest_id.cc b/chrome/browser/ash/guest_os/guest_id.cc
new file mode 100644
index 0000000..4c981149
--- /dev/null
+++ b/chrome/browser/ash/guest_os/guest_id.cc
@@ -0,0 +1,54 @@
+// 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/browser/ash/guest_os/guest_id.h"
+
+#include "chrome/browser/ash/crostini/crostini_pref_names.h"
+
+namespace guest_os {
+
+GuestId::GuestId(std::string vm_name, std::string container_name) noexcept
+    : vm_name(std::move(vm_name)), container_name(std::move(container_name)) {}
+
+GuestId::GuestId(const base::Value& value) noexcept {
+  const base::Value::Dict* dict = value.GetIfDict();
+  const std::string* vm = nullptr;
+  const std::string* container = nullptr;
+  if (dict != nullptr) {
+    vm = dict->FindString(crostini::prefs::kVmKey);
+    container = dict->FindString(crostini::prefs::kContainerKey);
+  }
+  vm_name = vm ? *vm : "";
+  container_name = container ? *container : "";
+}
+
+base::flat_map<std::string, std::string> GuestId::ToMap() const {
+  base::flat_map<std::string, std::string> extras;
+  extras[crostini::prefs::kVmKey] = vm_name;
+  extras[crostini::prefs::kContainerKey] = container_name;
+  return extras;
+}
+
+base::Value::Dict GuestId::ToDictValue() const {
+  base::Value::Dict dict;
+  dict.Set(crostini::prefs::kVmKey, vm_name);
+  dict.Set(crostini::prefs::kContainerKey, container_name);
+  return dict;
+}
+
+bool operator<(const GuestId& lhs, const GuestId& rhs) noexcept {
+  const auto result = lhs.vm_name.compare(rhs.vm_name);
+  return result < 0 || (result == 0 && lhs.container_name < rhs.container_name);
+}
+
+bool operator==(const GuestId& lhs, const GuestId& rhs) noexcept {
+  return lhs.vm_name == rhs.vm_name && lhs.container_name == rhs.container_name;
+}
+
+std::ostream& operator<<(std::ostream& ostream, const GuestId& container_id) {
+  return ostream << "(vm: \"" << container_id.vm_name << "\" container: \""
+                 << container_id.container_name << "\")";
+}
+
+}  // namespace guest_os
diff --git a/chrome/browser/ash/guest_os/guest_id.h b/chrome/browser/ash/guest_os/guest_id.h
new file mode 100644
index 0000000..4fff43a
--- /dev/null
+++ b/chrome/browser/ash/guest_os/guest_id.h
@@ -0,0 +1,38 @@
+// 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 CHROME_BROWSER_ASH_GUEST_OS_GUEST_ID_H_
+#define CHROME_BROWSER_ASH_GUEST_OS_GUEST_ID_H_
+
+#include <ostream>
+#include <string>
+
+#include "base/containers/flat_map.h"
+#include "base/values.h"
+
+namespace guest_os {
+
+// A unique identifier for our guests.
+struct GuestId {
+  GuestId(std::string vm_name, std::string container_name) noexcept;
+  explicit GuestId(const base::Value&) noexcept;
+
+  base::flat_map<std::string, std::string> ToMap() const;
+  base::Value::Dict ToDictValue() const;
+
+  std::string vm_name;
+  std::string container_name;
+};
+
+bool operator<(const GuestId& lhs, const GuestId& rhs) noexcept;
+bool operator==(const GuestId& lhs, const GuestId& rhs) noexcept;
+inline bool operator!=(const GuestId& lhs, const GuestId& rhs) noexcept {
+  return !(lhs == rhs);
+}
+
+std::ostream& operator<<(std::ostream& ostream, const GuestId& container_id);
+
+}  // namespace guest_os
+
+#endif  // CHROME_BROWSER_ASH_GUEST_OS_GUEST_ID_H_
diff --git a/chrome/browser/ash/guest_os/guest_id_unittest.cc b/chrome/browser/ash/guest_os/guest_id_unittest.cc
new file mode 100644
index 0000000..3a45f29
--- /dev/null
+++ b/chrome/browser/ash/guest_os/guest_id_unittest.cc
@@ -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.
+
+#include "chrome/browser/ash/guest_os/guest_id.h"
+
+#include "base/values.h"
+#include "chrome/browser/ash/crostini/crostini_pref_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace guest_os {
+
+using GuestIdTest = testing::Test;
+
+TEST_F(GuestIdTest, GuestIdEquality) {
+  auto container1 = GuestId{"test1", "test2"};
+  auto container2 = GuestId{"test1", "test2"};
+  auto container3 = GuestId{"test2", "test1"};
+
+  ASSERT_TRUE(container1 == container2);
+  ASSERT_FALSE(container1 == container3);
+  ASSERT_FALSE(container2 == container3);
+}
+
+TEST_F(GuestIdTest, GuestIdFromDictValue) {
+  base::Value dict(base::Value::Type::DICT);
+  dict.SetStringKey(crostini::prefs::kVmKey, "foo");
+  dict.SetStringKey(crostini::prefs::kContainerKey, "bar");
+  EXPECT_TRUE(GuestId(dict) == GuestId("foo", "bar"));
+}
+
+TEST_F(GuestIdTest, GuestIdFromNonDictValue) {
+  base::Value non_dict("not a dict value");
+  EXPECT_TRUE(GuestId(non_dict) == GuestId("", ""));
+}
+
+}  // namespace guest_os
diff --git a/chrome/browser/ash/guest_os/guest_os_launcher.cc b/chrome/browser/ash/guest_os/guest_os_launcher.cc
index 207b137..c43948d8 100644
--- a/chrome/browser/ash/guest_os/guest_os_launcher.cc
+++ b/chrome/browser/ash/guest_os/guest_os_launcher.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_simple_types.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_service.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_manager.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_manager_factory.h"
diff --git a/chrome/browser/ash/guest_os/guest_os_registry_service.cc b/chrome/browser/ash/guest_os/guest_os_registry_service.cc
index a0455bfe..1b0c1c7 100644
--- a/chrome/browser/ash/guest_os/guest_os_registry_service.cc
+++ b/chrome/browser/ash/guest_os/guest_os_registry_service.cc
@@ -678,8 +678,7 @@
           &GuestOsRegistryService::ApplyContainerBadge,
           weak_ptr_factory_.GetWeakPtr(),
           crostini::GetContainerBadgeColor(
-              profile_,
-              crostini::ContainerId(reg->VmName(), reg->ContainerName())),
+              profile_, guest_os::GuestId(reg->VmName(), reg->ContainerName())),
           std::move(callback));
     }
   }
@@ -998,7 +997,7 @@
 }
 
 void GuestOsRegistryService::ContainerBadgeColorChanged(
-    const crostini::ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   std::vector<std::string> updated_apps;
 
   for (const auto& it : GetAllRegisteredApps()) {
@@ -1109,8 +1108,7 @@
   }
 
   crostini::CrostiniManager::GetForProfile(profile_)->GetContainerAppIcons(
-      crostini::ContainerId(registration->VmName(),
-                            registration->ContainerName()),
+      guest_os::GuestId(registration->VmName(), registration->ContainerName()),
       desktop_file_ids,
       ash::SharedAppListConfig::instance().default_grid_icon_dimension(),
       icon_scale,
diff --git a/chrome/browser/ash/guest_os/guest_os_registry_service.h b/chrome/browser/ash/guest_os/guest_os_registry_service.h
index d2abf62..411d622 100644
--- a/chrome/browser/ash/guest_os/guest_os_registry_service.h
+++ b/chrome/browser/ash/guest_os/guest_os_registry_service.h
@@ -17,7 +17,7 @@
 #include "base/values.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/ash/crostini/crostini_simple_types.h"
-#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chromeos/dbus/vm_applications/apps.pb.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
@@ -225,7 +225,7 @@
   // Inform the registry that the badge color for `container_id` has changed. In
   // practice, this sends an update notification for all apps associated with
   // this container, which will prompt the icons to be regenerated.
-  void ContainerBadgeColorChanged(const crostini::ContainerId& container_id);
+  void ContainerBadgeColorChanged(const guest_os::GuestId& container_id);
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path.cc b/chrome/browser/ash/guest_os/guest_os_share_path.cc
index ac41ed8..f0d505e 100644
--- a/chrome/browser/ash/guest_os/guest_os_share_path.cc
+++ b/chrome/browser/ash/guest_os/guest_os_share_path.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/ash/file_manager/volume_manager.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/guest_os_pref_names.h"
 #include "chrome/browser/ash/guest_os/guest_os_share_path_factory.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_manager.h"
@@ -398,8 +399,7 @@
       // kCrostiniDefaultContainerName is not used in the following function
       // since we are only starting the VM.
       crostini_manager->RestartCrostiniWithOptions(
-          crostini::ContainerId(vm_name,
-                                crostini::kCrostiniDefaultContainerName),
+          guest_os::GuestId(vm_name, crostini::kCrostiniDefaultContainerName),
           std::move(options),
           base::BindOnce(&OnVmRestartedForSeneschal, profile_, vm_name,
                          std::move(callback), std::move(request)));
diff --git a/chrome/browser/ash/guest_os/guest_os_test_helpers.cc b/chrome/browser/ash/guest_os/guest_os_test_helpers.cc
index 131037d..046ec82 100644
--- a/chrome/browser/ash/guest_os/guest_os_test_helpers.cc
+++ b/chrome/browser/ash/guest_os/guest_os_test_helpers.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ash/guest_os/guest_os_test_helpers.h"
+#include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
 
 #ifndef CHROME_BROWSER_ASH_GUEST_OS_PUBLIC_GUEST_OS_TEST_HELPERS_H_
@@ -14,7 +15,7 @@
     : profile_(nullptr), container_id_(crostini::DefaultContainerId()) {}
 
 MockMountProvider::MockMountProvider(Profile* profile,
-                                     crostini::ContainerId container_id)
+                                     guest_os::GuestId container_id)
     : profile_(profile), container_id_(container_id) {}
 
 std::string MockMountProvider::DisplayName() {
@@ -25,7 +26,7 @@
   return profile_;
 }
 
-crostini::ContainerId MockMountProvider::ContainerId() {
+guest_os::GuestId MockMountProvider::GuestId() {
   return container_id_;
 }
 
diff --git a/chrome/browser/ash/guest_os/guest_os_test_helpers.h b/chrome/browser/ash/guest_os/guest_os_test_helpers.h
index afda07be..eb4eacbc 100644
--- a/chrome/browser/ash/guest_os/guest_os_test_helpers.h
+++ b/chrome/browser/ash/guest_os/guest_os_test_helpers.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_GUEST_OS_GUEST_OS_TEST_HELPERS_H_
 #define CHROME_BROWSER_ASH_GUEST_OS_GUEST_OS_TEST_HELPERS_H_
 
-#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_mount_provider.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
 
@@ -13,16 +13,16 @@
 class MockMountProvider : public GuestOsMountProvider {
  public:
   MockMountProvider();
-  MockMountProvider(Profile* profile, crostini::ContainerId container_id);
+  MockMountProvider(Profile* profile, guest_os::GuestId container_id);
 
   std::string DisplayName() override;
   Profile* profile() override;
-  crostini::ContainerId ContainerId() override;
+  guest_os::GuestId GuestId() override;
 
   VmType vm_type() override;
 
   Profile* profile_;
-  crostini::ContainerId container_id_;
+  guest_os::GuestId container_id_;
 };
 }  // namespace guest_os
 
diff --git a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
index 3b97bde..6b2386b 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
+++ b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.cc
@@ -79,7 +79,7 @@
  public:
   explicit GuestOsMountProviderInner(Profile* profile,
                                      std::string display_name,
-                                     crostini::ContainerId container_id,
+                                     guest_os::GuestId container_id,
                                      int cid,
                                      int port,
                                      base::FilePath homedir,
@@ -130,7 +130,7 @@
 
   Profile* profile_;
   std::string display_name_;
-  crostini::ContainerId container_id_;
+  guest_os::GuestId container_id_;
   std::string mount_label_;
   int cid_;
   int port_;  // vsock port
@@ -145,7 +145,7 @@
 void GuestOsMountProvider::Mount(base::OnceCallback<void(bool)> callback) {
   if (!callback_) {
     callback_ = std::make_unique<GuestOsMountProviderInner>(
-        profile(), DisplayName(), ContainerId(), cid(), port(), homedir(),
+        profile(), DisplayName(), GuestId(), cid(), port(), homedir(),
         vm_type());
   }
   callback_->Get(base::BindOnce(
diff --git a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.h b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.h
index b8bd9a7..81c3d4ca 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_mount_provider.h
+++ b/chrome/browser/ash/guest_os/public/guest_os_mount_provider.h
@@ -8,7 +8,7 @@
 #include <string>
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
-#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/public/types.h"
 
 class Profile;
@@ -30,8 +30,7 @@
   // The localised name to show in UI elements such as the files app sidebar.
   virtual std::string DisplayName() = 0;
 
-  // TODO(crbug/1293229): Make ContainerId generic and in guest_os namespace.
-  virtual crostini::ContainerId ContainerId() = 0;
+  virtual guest_os::GuestId GuestId() = 0;
 
   // TODO(crbug/1293229): How exactly we perform an SFTP mount is TBD, so these
   // are subject to change. For now we put random fake values in so we don't
diff --git a/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc b/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
index bb48914..419ea167 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
+++ b/chrome/browser/ash/guest_os/public/guest_os_mount_provider_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/file_manager/volume_manager.h"
 #include "chrome/browser/ash/file_manager/volume_manager_factory.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/guest_os/guest_os_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/cros_disks/cros_disks_client.h"
@@ -52,8 +53,7 @@
     // DiskMountManager::InitializeForTesting takes ownership and works with
     // a raw pointer, hence the new with no matching delete.
     disk_manager_ = new ash::disks::MockDiskMountManager;
-    provider_ =
-        std::make_unique<MockMountProvider>(profile_.get(), kContainerId);
+    provider_ = std::make_unique<MockMountProvider>(profile_.get(), kGuestId);
     file_manager::VolumeManagerFactory::GetInstance()->SetTestingFactory(
         profile_.get(), base::BindRepeating(&BuildVolumeManager));
 
@@ -104,10 +104,9 @@
             Invoke(this, &GuestOsMountProviderTest::NotifyMountEvent));
   }
 
-  // guestos_${UserHash}_${encode(kContainerId.ToString())}. Note that UserHash
+  // guestos_${UserHash}_${encode(kGuestId.ToString())}. Note that UserHash
   // is an empty string in these tests.
-  const crostini::ContainerId kContainerId =
-      crostini::ContainerId("cow", "ptery/daccy");
+  const guest_os::GuestId kGuestId = guest_os::GuestId("cow", "ptery/daccy");
   const std::string kMountName = std::string{"guestos++cow+ptery%2Fdaccy"};
 
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h b/chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h
index 45abe13..766b54cf 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h
+++ b/chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_ASH_GUEST_OS_PUBLIC_GUEST_OS_TERMINAL_PROVIDER_H_
 
 #include <string>
-#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace guest_os {
@@ -25,7 +25,7 @@
   // TODO(b/233287586): While we're migrating, some Crostini-specific code still
   // needs a ContainerId. Eventually this should always be nullopt and then
   // removed.
-  virtual absl::optional<crostini::ContainerId> CrostiniContainerId() = 0;
+  virtual absl::optional<guest_os::GuestId> CrostiniContainerId() = 0;
 
  private:
 };
diff --git a/chrome/browser/ash/guest_os/public/guest_os_terminal_provider_registry.cc b/chrome/browser/ash/guest_os/public/guest_os_terminal_provider_registry.cc
index 73009867..65e75024 100644
--- a/chrome/browser/ash/guest_os/public/guest_os_terminal_provider_registry.cc
+++ b/chrome/browser/ash/guest_os/public/guest_os_terminal_provider_registry.cc
@@ -7,6 +7,8 @@
 #include <climits>
 #include <memory>
 #include <vector>
+
+#include "base/strings/string_number_conversions.h"
 #include "chrome/browser/ash/guest_os/public/guest_os_terminal_provider.h"
 #include "content/public/browser/browser_thread.h"
 
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
index d50bcf4..231705e 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine_observer.cc
@@ -399,12 +399,13 @@
 }
 
 uint32_t Utf16ToCodepoint(const std::u16string& str) {
-  size_t index = 0;
+  int32_t index = 0;
   base_icu::UChar32 codepoint = 0;
   base::ReadUnicodeCharacter(str.data(), str.length(), &index, &codepoint);
 
   // Should only contain a single codepoint.
-  DCHECK_EQ(index, str.length() - 1);
+  DCHECK_GE(index, 0);
+  DCHECK_EQ(static_cast<size_t>(index), str.length() - 1);
   return codepoint;
 }
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
index 438eaf63..6f3e2d4 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -72,15 +72,16 @@
 using ash::personalization_app::GetUser;
 
 constexpr int kLocalImageThumbnailSizeDip = 256;
+constexpr int kCurrentWallpaperThumbnailSizeDip = 512;
 
 const gfx::ImageSkia GetResizedImage(const gfx::ImageSkia& image) {
   // Resize the image maintaining our aspect ratio.
   float aspect_ratio =
       static_cast<float>(image.width()) / static_cast<float>(image.height());
-  int height = kLocalImageThumbnailSizeDip;
+  int height = kCurrentWallpaperThumbnailSizeDip;
   int width = static_cast<int>(aspect_ratio * height);
-  if (width > kLocalImageThumbnailSizeDip) {
-    width = kLocalImageThumbnailSizeDip;
+  if (width > kCurrentWallpaperThumbnailSizeDip) {
+    width = kCurrentWallpaperThumbnailSizeDip;
     height = static_cast<int>(width / aspect_ratio);
   }
   return gfx::ImageSkiaOperations::CreateResizedImage(
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
index 9f3e473b..d8b22d5 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -444,9 +444,9 @@
   EXPECT_EQ(ash::WallpaperType::kOnline, current->type);
   EXPECT_EQ(ash::WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED,
             current->layout);
-  // Data url of a solid black image scaled up to 256x256.
+  // Data url of a solid black image scaled up to 512x512.
   EXPECT_EQ(webui::GetBitmapDataUrl(
-                *CreateSolidImageSkia(256, 256, SK_ColorBLACK).bitmap()),
+                *CreateSolidImageSkia(512, 512, SK_ColorBLACK).bitmap()),
             current->url);
 }
 
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn
index d286fa4f..5e6a9b5 100644
--- a/chrome/browser/back_press/android/BUILD.gn
+++ b/chrome/browser/back_press/android/BUILD.gn
@@ -24,8 +24,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java" ]
 
   deps = [
@@ -35,7 +33,6 @@
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
     "//components/browser_ui/widget/android:java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_activity_activity_java",
     "//third_party/junit:junit",
   ]
diff --git a/chrome/browser/bluetooth/android/BUILD.gn b/chrome/browser/bluetooth/android/BUILD.gn
index 4036a80..3bc2f12 100644
--- a/chrome/browser/bluetooth/android/BUILD.gn
+++ b/chrome/browser/bluetooth/android/BUILD.gn
@@ -43,8 +43,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "junit/src/org/chromium/chrome/browser/bluetooth/BluetoothNotificationManagerTest.java" ]
 
   deps = [
@@ -54,7 +52,6 @@
     "//chrome/test/android:chrome_java_unit_test_support",
     "//components/browser_ui/notifications/android:test_support_java",
     "//components/url_formatter/android:url_formatter_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
diff --git a/chrome/browser/browser_controls/android/BUILD.gn b/chrome/browser/browser_controls/android/BUILD.gn
index 3e7b0cd..dbe67c8 100644
--- a/chrome/browser/browser_controls/android/BUILD.gn
+++ b/chrome/browser/browser_controls/android/BUILD.gn
@@ -26,7 +26,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegateTest.java" ]
   deps = [
     ":java",
@@ -34,7 +33,6 @@
     "//base:base_junit_test_support",
     "//cc:cc_java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index d0becae..af46fb2 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -3142,6 +3142,7 @@
     "../ash/file_system_provider/service_unittest.cc",
     "../ash/file_system_provider/throttled_file_system_unittest.cc",
     "../ash/fusebox/fusebox_util_unittest.cc",
+    "../ash/guest_os/guest_id_unittest.cc",
     "../ash/guest_os/guest_os_diagnostics_builder_unittest.cc",
     "../ash/guest_os/guest_os_external_protocol_handler_unittest.cc",
     "../ash/guest_os/guest_os_mime_types_service_unittest.cc",
diff --git a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
index 7871eb2..dad50da2 100644
--- a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
+++ b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
@@ -83,8 +83,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustBottomSheetMediatorTest.java",
     "javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageContextTest.java",
diff --git a/chrome/browser/commerce/price_tracking/android/BUILD.gn b/chrome/browser/commerce/price_tracking/android/BUILD.gn
index e2e9c23..16ed0646 100644
--- a/chrome/browser/commerce/price_tracking/android/BUILD.gn
+++ b/chrome/browser/commerce/price_tracking/android/BUILD.gn
@@ -9,22 +9,22 @@
   sources = [ "java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java" ]
 }
 
-android_library("java") {
+android_library("public_java") {
   sources = [
+    "java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java",
     "java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingFeatures.java",
     "java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingUtilities.java",
   ]
 
   deps = [
     "//base:base_java",
-    "//chrome/browser/commerce/subscriptions/android:java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/notifications:java",
     "//chrome/browser/preferences:java",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/signin/services/android:java",
     "//chrome/browser/tabmodel:java",
     "//components/signin/public/android:java",
-    "//components/sync/android:sync_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
 }
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java
index 0d2e352..fcb50d77 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java
@@ -4,227 +4,42 @@
 
 package org.chromium.chrome.browser.price_tracking;
 
-import android.app.Activity;
 import android.app.Notification;
 import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
 import android.content.Intent;
-import android.net.Uri;
 import android.os.Build;
-import android.os.Bundle;
-import android.provider.Browser;
-import android.provider.Settings;
-import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import org.chromium.base.Callback;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.IntentUtils;
-import org.chromium.base.Log;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
-import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
-import org.chromium.chrome.browser.document.ChromeLauncherActivity;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.notifications.NotificationIntentInterceptor;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker.SystemNotificationType;
-import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscription;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscription.CommerceSubscriptionType;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscription.SubscriptionManagementType;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscription.TrackingIdType;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceFactory;
-import org.chromium.chrome.browser.subscriptions.SubscriptionsManager;
-import org.chromium.chrome.browser.subscriptions.SubscriptionsManagerImpl;
-import org.chromium.components.browser_ui.notifications.NotificationManagerProxy;
-import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl;
-import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer;
 
-import java.util.Locale;
-
-/**
- * Manage price drop notifications.
- */
-public class PriceDropNotificationManager {
-    private static final String TAG = "PriceDropNotif";
-    private static final String ACTION_APP_NOTIFICATION_SETTINGS =
-            "android.settings.APP_NOTIFICATION_SETTINGS";
-    private static final String EXTRA_APP_PACKAGE = "app_package";
-    private static final String EXTRA_APP_UID = "app_uid";
-    // The action ids should be the same as defined in the server, see {@link
-    // HandleProductUpdateEventsProducerModule}.
-    static final String ACTION_ID_VISIT_SITE = "visit_site";
-    static final String ACTION_ID_TURN_OFF_ALERT = "turn_off_alert";
-
-    static final String EXTRA_DESTINATION_URL =
-            "org.chromium.chrome.browser.price_tracking.DESTINATION_URL";
-    static final String EXTRA_ACTION_ID = "org.chromium.chrome.browser.price_tracking.ACTION_ID";
-    static final String EXTRA_OFFER_ID = "org.chromium.chrome.browser.price_tracking.OFFER_ID";
-    static final String EXTRA_PRODUCT_CLUSTER_ID =
-            "org.chromium.chrome.browser.price_tracking.PRODUCT_CLUSTER_ID";
-    static final String EXTRA_NOTIFICATION_ID =
-            "org.chromium.chrome.browser.price_tracking.NOTIFICATION_ID";
-
-    static final String CHROME_MANAGED_TIMESTAMPS =
-            ChromePreferenceKeys.PRICE_TRACKING_CHROME_MANAGED_NOTIFICATIONS_TIMESTAMPS;
-    static final String USER_MANAGED_TIMESTAMPS =
-            ChromePreferenceKeys.PRICE_TRACKING_USER_MANAGED_NOTIFICATIONS_TIMESTAMPS;
-
-    @VisibleForTesting
-    public static final String NOTIFICATION_ENABLED_HISTOGRAM =
-            "Commerce.PriceDrop.SystemNotificationEnabled";
-    @VisibleForTesting
-    public static final String NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM =
-            "Commerce.PriceDrops.ChromeManaged.NotificationCount";
-    @VisibleForTesting
-    public static final String NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM =
-            "Commerce.PriceDrops.UserManaged.NotificationCount";
-
-    private static NotificationManagerProxy sNotificationManagerForTesting;
-    private static BookmarkBridge sBookmarkBridgeForTesting;
-
-    /**
-     * Used to host click logic for "turn off alert" action intent.
-     */
-    public static class TrampolineActivity extends Activity {
-        @Override
-        protected void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            Intent intent = getIntent();
-            String destinationUrl = IntentUtils.safeGetStringExtra(intent, EXTRA_DESTINATION_URL);
-            String actionId = IntentUtils.safeGetStringExtra(intent, EXTRA_ACTION_ID);
-            String offerId = IntentUtils.safeGetStringExtra(intent, EXTRA_OFFER_ID);
-            String clusterId = IntentUtils.safeGetStringExtra(intent, EXTRA_PRODUCT_CLUSTER_ID);
-            int notificationId = IntentUtils.safeGetIntExtra(intent, EXTRA_NOTIFICATION_ID, 0);
-
-            dismissNotification(notificationId);
-
-            if (TextUtils.isEmpty(offerId)) {
-                Log.e(TAG, "No offer id is provided when handling turn off alert action.");
-                finish();
-                return;
-            }
-
-            // Handles "turn off alert" action button click.
-            ChromeBrowserInitializer.getInstance().runNowOrAfterFullBrowserStarted(() -> {
-                PriceDropNotificationManager priceDropNotificationManager =
-                        PriceDropNotificationManagerFactory.create();
-                assert ACTION_ID_TURN_OFF_ALERT.equals(actionId)
-                    : "Currently only turn off alert action uses this activity.";
-                priceDropNotificationManager.onNotificationActionClicked(
-                        actionId, destinationUrl, offerId, clusterId, /*recordMetrics=*/false);
-                // Finish immediately. Could be better to have a callback from shopping backend.
-                finish();
-            });
-        }
-    }
-
-    /**
-     * Used to dismiss the notification after content click or "visit site" action click.
-     */
-    public static class DismissNotificationChromeActivity extends ChromeLauncherActivity {
-        @Override
-        public void onCreate(@Nullable Bundle savedInstanceState) {
-            int notificationId = IntentUtils.safeGetIntExtra(getIntent(), EXTRA_NOTIFICATION_ID, 0);
-            dismissNotification(notificationId);
-            super.onCreate(savedInstanceState);
-            finish();
-        }
-    }
-
-    private final Context mContext;
-    private final NotificationManagerProxy mNotificationManager;
-    private final SharedPreferencesManager mPreferencesManager;
-
-    // TODO(shaktisahu): Remove this after landing downstream changes.
-    public PriceDropNotificationManager() {
-        this(ContextUtils.getApplicationContext(),
-                new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()));
-    }
-
-    /**
-     * Constructor.
-     * @param context The application context.
-     * @param notificationManagerProxy The {@link NotificationManagerProxy} for sending
-     *         notifications.
-     */
-    public PriceDropNotificationManager(
-            Context context, NotificationManagerProxy notificationManagerProxy) {
-        mContext = context;
-        mNotificationManager = notificationManagerProxy;
-        mPreferencesManager = SharedPreferencesManager.getInstance();
-    }
-
+/** Manage price drop notifications. */
+public interface PriceDropNotificationManager {
     /**
      * @return Whether the price drop notification type is enabled. For now it is used in downstream
      *         which could influence the Chime registration.
      */
-    public boolean isEnabled() {
-        return PriceTrackingFeatures.getPriceTrackingNotificationsEnabled();
-    }
+    boolean isEnabled();
 
     /**
      * @return Whether price drop notifications can be posted.
      */
-    public boolean canPostNotification() {
-        if (!areAppNotificationsEnabled()
-                || !PriceTrackingFeatures.isPriceDropNotificationEligible()) {
-            return false;
-        }
-
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            NotificationChannel channel = getNotificationChannel();
-            if (channel == null || channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
-                return false;
-            }
-        }
-
-        return true;
-    }
+    boolean canPostNotification();
 
     /**
      * @return Whether price drop notifications can be posted and record user opt-in metrics.
      */
-    public boolean canPostNotificationWithMetricsRecorded() {
-        if (!PriceTrackingFeatures.isPriceDropNotificationEligible()) return false;
-        boolean isSystemNotificationEnabled = areAppNotificationsEnabled();
-        RecordHistogram.recordBooleanHistogram(
-                NOTIFICATION_ENABLED_HISTOGRAM, isSystemNotificationEnabled);
-        if (!isSystemNotificationEnabled) return false;
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return true;
-
-        NotificationChannel channel = getNotificationChannel();
-        boolean isChannelCreated = channel != null;
-        RecordHistogram.recordBooleanHistogram(
-                "Commerce.PriceDrop.NotificationChannelCreated", isChannelCreated);
-        if (!isChannelCreated) return false;
-        boolean isChannelBlocked = channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
-        RecordHistogram.recordBooleanHistogram(
-                "Commerce.PriceDrop.NotificationChannelBlocked", isChannelBlocked);
-        return !isChannelBlocked;
-    }
+    boolean canPostNotificationWithMetricsRecorded();
 
     /**
      * Record UMAs after posting price drop notifications.
      *
      * @param notification that has been posted.
      */
-    public void onNotificationPosted(@Nullable Notification notification) {
-        NotificationUmaTracker.getInstance().onNotificationShown(
-                NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS, notification);
-    }
+    void onNotificationPosted(@Nullable Notification notification);
 
     /**
      * When user clicks the notification, they will be sent to the tab with price drop which
@@ -232,11 +47,7 @@
      *
      * @param url of the tab which triggered the notification.
      */
-    public void onNotificationClicked(String url) {
-        NotificationUmaTracker.getInstance().onNotificationContentClick(
-                NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
-                NotificationIntentInterceptor.INVALID_CREATE_TIME);
-    }
+    void onNotificationClicked(String url);
 
     /**
      * Handles the notification action click events.
@@ -247,10 +58,8 @@
      * @param recordMetrics Whether to record metrics using {@link NotificationUmaTracker}. Only
      *         Chime notification code path should set this to true.
      */
-    public void onNotificationActionClicked(
-            String actionId, String url, @Nullable String offerId, boolean recordMetrics) {
-        onNotificationActionClicked(actionId, url, offerId, null, recordMetrics);
-    }
+    void onNotificationActionClicked(
+            String actionId, String url, @Nullable String offerId, boolean recordMetrics);
 
     /**
      * Handles the notification action click events.
@@ -262,79 +71,11 @@
      * @param recordMetrics Whether to record metrics using {@link NotificationUmaTracker}. Only
      *         Chime notification code path should set this to true.
      */
-    public void onNotificationActionClicked(String actionId, String url, @Nullable String offerId,
-            @Nullable String clusterId, boolean recordMetrics) {
-        if (actionId.equals(ACTION_ID_VISIT_SITE) && recordMetrics) {
-            NotificationUmaTracker.getInstance().onNotificationActionClick(
-                    NotificationUmaTracker.ActionType.PRICE_DROP_VISIT_SITE,
-                    NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
-                    NotificationIntentInterceptor.INVALID_CREATE_TIME);
-        } else if (actionId.equals(ACTION_ID_TURN_OFF_ALERT)) {
-            if (offerId == null && clusterId == null) return;
-            SubscriptionsManagerImpl subscriptionsManager =
-                    (new CommerceSubscriptionsServiceFactory())
-                            .getForLastUsedProfile()
-                            .getSubscriptionsManager();
-            Callback<Integer> callback = (status) -> {
-                assert status
-                        == SubscriptionsManager.StatusCode.OK : "Failed to remove subscriptions.";
-                Log.e(TAG,
-                        String.format(
-                                Locale.US, "Failed to remove subscriptions. Status: %d", status));
-            };
-            final BookmarkBridge bookmarkBridge;
-            if (sBookmarkBridgeForTesting != null) {
-                bookmarkBridge = sBookmarkBridgeForTesting;
-            } else {
-                bookmarkBridge = new BookmarkBridge(Profile.getLastUsedRegularProfile());
-            }
-
-            Runnable unsubscribeRunnable = () -> {
-                if (offerId != null) {
-                    subscriptionsManager.unsubscribe(
-                            new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId,
-                                    SubscriptionManagementType.CHROME_MANAGED,
-                                    TrackingIdType.OFFER_ID),
-                            callback);
-                }
-                if (clusterId != null) {
-                    subscriptionsManager.unsubscribe(
-                            new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK,
-                                    clusterId, SubscriptionManagementType.USER_MANAGED,
-                                    TrackingIdType.PRODUCT_CLUSTER_ID),
-                            callback);
-                }
-            };
-
-            // Only attempt to unsubscribe once the corresponding bookmarks can also be updated.
-            if (bookmarkBridge.isBookmarkModelLoaded()) {
-                unsubscribeRunnable.run();
-            } else {
-                bookmarkBridge.addObserver(new BookmarkBridge.BookmarkModelObserver() {
-                    @Override
-                    public void bookmarkModelLoaded() {
-                        unsubscribeRunnable.run();
-                        bookmarkBridge.removeObserver(this);
-                    }
-
-                    @Override
-                    public void bookmarkModelChanged() {}
-                });
-            }
-
-            if (recordMetrics) {
-                NotificationUmaTracker.getInstance().onNotificationActionClick(
-                        NotificationUmaTracker.ActionType.PRICE_DROP_TURN_OFF_ALERT,
-                        NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
-                        NotificationIntentInterceptor.INVALID_CREATE_TIME);
-            }
-        }
-    }
+    void onNotificationActionClicked(String actionId, String url, @Nullable String offerId,
+            @Nullable String clusterId, boolean recordMetrics);
 
     @Deprecated
-    public Intent getNotificationClickIntent(String url) {
-        return getNotificationClickIntent(url, 0);
-    }
+    Intent getNotificationClickIntent(String url);
 
     /**
      * @return The intent that we will use to send users to the tab which triggered the
@@ -343,30 +84,14 @@
      * @param url of the tab which triggered the notification.
      * @param notificationId the notification id.
      */
-    public Intent getNotificationClickIntent(String url, int notificationId) {
-        Intent intent =
-                new Intent()
-                        .setAction(Intent.ACTION_VIEW)
-                        .setData(Uri.parse(url))
-                        .setClass(mContext, DismissNotificationChromeActivity.class)
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
-                        .putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName())
-                        .putExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true)
-                        .putExtra(EXTRA_NOTIFICATION_ID, notificationId);
-        IntentUtils.addTrustedIntentExtras(intent);
-        return intent;
-    }
+    Intent getNotificationClickIntent(String url, int notificationId);
 
     @Deprecated
-    public Intent getNotificationActionClickIntent(String actionId, String url, String offerId) {
-        return getNotificationActionClickIntent(actionId, url, offerId, null, 0);
-    }
+    Intent getNotificationActionClickIntent(String actionId, String url, String offerId);
 
     @Deprecated
-    public Intent getNotificationActionClickIntent(
-            String actionId, String url, String offerId, String clusterId) {
-        return getNotificationActionClickIntent(actionId, url, offerId, clusterId, 0);
-    }
+    Intent getNotificationActionClickIntent(
+            String actionId, String url, String offerId, String clusterId);
 
     /**
      * Gets the notification action click intents.
@@ -377,153 +102,54 @@
      * @param clusterId The cluster id of the product.
      * @param notificationId the notification id.
      */
-    public Intent getNotificationActionClickIntent(
-            String actionId, String url, String offerId, String clusterId, int notificationId) {
-        if (ACTION_ID_VISIT_SITE.equals(actionId)) {
-            return getNotificationClickIntent(url, notificationId);
-        }
-        if (ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
-            Intent intent = new Intent(mContext, TrampolineActivity.class);
-            intent.putExtra(EXTRA_DESTINATION_URL, url);
-            intent.putExtra(EXTRA_ACTION_ID, actionId);
-            intent.putExtra(EXTRA_OFFER_ID, offerId);
-            if (clusterId != null) intent.putExtra(EXTRA_PRODUCT_CLUSTER_ID, clusterId);
-            intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId);
-            IntentUtils.addTrustedIntentExtras(intent);
-            return intent;
-        }
-        return null;
-    }
+    Intent getNotificationActionClickIntent(
+            String actionId, String url, String offerId, String clusterId, int notificationId);
 
     /**
      * @return Whether app notifications are enabled.
      */
-    public boolean areAppNotificationsEnabled() {
-        if (sNotificationManagerForTesting != null) {
-            return sNotificationManagerForTesting.areNotificationsEnabled();
-        }
-        return mNotificationManager.areNotificationsEnabled();
-    }
+    boolean areAppNotificationsEnabled();
 
     /**
      * Create the notification channel for price drop notifications.
      */
     @RequiresApi(Build.VERSION_CODES.O)
-    public void createNotificationChannel() {
-        NotificationChannel channel = getNotificationChannel();
-        if (channel != null) return;
-        new ChannelsInitializer(mNotificationManager, ChromeChannelDefinitions.getInstance(),
-                mContext.getResources())
-                .ensureInitialized(ChromeChannelDefinitions.ChannelId.PRICE_DROP);
-    }
+    void createNotificationChannel();
 
     /**
      * Send users to notification settings so they can manage price drop notifications.
      */
-    public void launchNotificationSettings() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            // Make sure the channel is initialized before sending users to the settings.
-            createNotificationChannel();
-        }
-        mContext.startActivity(getNotificationSettingsIntent());
-        // Disable PriceAlertsMessageCard after the first time we send users to notification
-        // settings.
-        PriceTrackingUtilities.disablePriceAlertsMessageCard();
-    }
+    void launchNotificationSettings();
 
     /**
      * @return The intent that we will use to send users to notification settings.
      */
     @VisibleForTesting
-    public Intent getNotificationSettingsIntent() {
-        Intent intent = new Intent();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            if (areAppNotificationsEnabled()) {
-                intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
-                intent.putExtra(Settings.EXTRA_APP_PACKAGE, mContext.getPackageName());
-                intent.putExtra(
-                        Settings.EXTRA_CHANNEL_ID, ChromeChannelDefinitions.ChannelId.PRICE_DROP);
-            } else {
-                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
-                intent.putExtra(Settings.EXTRA_APP_PACKAGE, mContext.getPackageName());
-            }
-        } else {
-            intent.setAction(ACTION_APP_NOTIFICATION_SETTINGS);
-            intent.putExtra(EXTRA_APP_PACKAGE, mContext.getPackageName());
-            intent.putExtra(EXTRA_APP_UID, mContext.getApplicationInfo().uid);
-        }
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
+    Intent getNotificationSettingsIntent();
 
     /**
      * @return The price drop notification channel.
      */
     @VisibleForTesting
     @RequiresApi(Build.VERSION_CODES.O)
-    public NotificationChannel getNotificationChannel() {
-        return mNotificationManager.getNotificationChannel(
-                ChromeChannelDefinitions.ChannelId.PRICE_DROP);
-    }
-
-    /**
-     * Set notificationManager for testing.
-     *
-     * @param notificationManager that will be set.
-     */
-    @VisibleForTesting
-    public static void setNotificationManagerForTesting(
-            NotificationManagerProxy notificationManager) {
-        sNotificationManagerForTesting = notificationManager;
-    }
-
-    /**
-     * Set a mock BookmarkBridge for testing so we don't need to access Profile.
-     *
-     * @param bookmarkBridge The bookmark bridge to use.
-     */
-    @VisibleForTesting
-    public static void setBookmarkBridgeForTesting(BookmarkBridge bookmarkBridge) {
-        sBookmarkBridgeForTesting = bookmarkBridge;
-    }
+    NotificationChannel getNotificationChannel();
 
     /**
      * Delete price drop notification channel for testing.
      */
     @VisibleForTesting
     @RequiresApi(Build.VERSION_CODES.O)
-    public void deleteChannelForTesting() {
-        mNotificationManager.deleteNotificationChannel(
-                ChromeChannelDefinitions.ChannelId.PRICE_DROP);
-    }
+    void deleteChannelForTesting();
 
     /**
      * Record how many notifications are shown in the given window per management type.
      */
-    public void recordMetricsForNotificationCounts() {
-        RecordHistogram.recordCount100Histogram(NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM,
-                updateNotificationTimestamps(
-                        SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, false));
-        RecordHistogram.recordCount100Histogram(NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM,
-                updateNotificationTimestamps(
-                        SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, false));
-    }
+    void recordMetricsForNotificationCounts();
 
     /**
      * Check if the shown notifications in given window have reached the max allowed number.
      */
-    boolean hasReachedMaxAllowedNotificationNumber(@SystemNotificationType int type) {
-        boolean hasReached = updateNotificationTimestamps(type, false)
-                >= PriceTrackingNotificationConfig.getMaxAllowedNotificationNumber(type);
-        String managementType = notificationTypeToManagementType(type);
-        if (managementType != null) {
-            RecordHistogram.recordBooleanHistogram(
-                    String.format(Locale.US, "Commerce.PriceDrops.%s.NotificationReachedCap",
-                            managementType),
-                    hasReached);
-        }
-        return hasReached;
-    }
+    boolean hasReachedMaxAllowedNotificationNumber(@SystemNotificationType int type);
 
     /**
      * Update the stored notification timestamps. Outdated timestamps are removed and current
@@ -533,64 +159,5 @@
      * @param attachCurrentTime Whether to store current timestamp.
      * @return the number of stored timestamps after update.
      */
-    int updateNotificationTimestamps(@SystemNotificationType int type, boolean attachCurrentTime) {
-        long currentTime = System.currentTimeMillis();
-        JSONArray newTimestamps = new JSONArray();
-        try {
-            String oldSerializedTimestamps = getStoredNotificationTimestamps(type);
-            JSONArray oldTimestamps = new JSONArray(oldSerializedTimestamps);
-            for (int i = 0; i < oldTimestamps.length(); i++) {
-                long timestamp = oldTimestamps.getLong(i);
-                if (currentTime - timestamp > PriceTrackingNotificationConfig
-                                                      .getNotificationTimestampsStoreWindowMs()) {
-                    continue;
-                }
-                newTimestamps.put(timestamp);
-            }
-        } catch (JSONException e) {
-            Log.e(TAG,
-                    String.format(Locale.US, "Failed to parse notification timestamps. Details: %s",
-                            e.getMessage()));
-            // If one parse fails, we discard all data and reset the stored timestamps.
-            newTimestamps = new JSONArray();
-        }
-        if (attachCurrentTime) newTimestamps.put(currentTime);
-        writeSerializedNotificationTimestamps(type, newTimestamps.toString());
-        return newTimestamps.length();
-    }
-
-    private String getStoredNotificationTimestamps(@SystemNotificationType int type) {
-        String serializedTimestamps = "";
-        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
-            serializedTimestamps = mPreferencesManager.readString(CHROME_MANAGED_TIMESTAMPS, "");
-        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
-            serializedTimestamps = mPreferencesManager.readString(USER_MANAGED_TIMESTAMPS, "");
-        }
-        return serializedTimestamps;
-    }
-
-    private void writeSerializedNotificationTimestamps(
-            @SystemNotificationType int type, String serializedTimestamps) {
-        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
-            mPreferencesManager.writeString(CHROME_MANAGED_TIMESTAMPS, serializedTimestamps);
-        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
-            mPreferencesManager.writeString(USER_MANAGED_TIMESTAMPS, serializedTimestamps);
-        }
-    }
-
-    private String notificationTypeToManagementType(@SystemNotificationType int type) {
-        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
-            return "ChromeManaged";
-        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
-            return "UserManaged";
-        } else {
-            Log.e(TAG, "Invalid notification type.");
-            return null;
-        }
-    }
-
-    private static void dismissNotification(int notificationId) {
-        new NotificationManagerProxyImpl(ContextUtils.getApplicationContext())
-                .cancel(PriceDropNotifier.NOTIFICATION_TAG, notificationId);
-    }
+    int updateNotificationTimestamps(@SystemNotificationType int type, boolean attachCurrentTime);
 }
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerFactory.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerFactory.java
index db26a33..32d3d1f4 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerFactory.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerFactory.java
@@ -16,7 +16,7 @@
 public class PriceDropNotificationManagerFactory {
     /** Builds a {@link PriceDropNotificationManager} instance. */
     public static PriceDropNotificationManager create() {
-        return new PriceDropNotificationManager(ContextUtils.getApplicationContext(),
+        return new PriceDropNotificationManagerImpl(ContextUtils.getApplicationContext(),
                 new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()));
     }
 
@@ -29,6 +29,6 @@
      */
     public static PriceDropNotificationManager create(
             Context context, NotificationManagerProxy notificationManagerProxy) {
-        return new PriceDropNotificationManager(context, notificationManagerProxy);
+        return new PriceDropNotificationManagerImpl(context, notificationManagerProxy);
     }
 }
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerImpl.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerImpl.java
new file mode 100644
index 0000000..26ea4164
--- /dev/null
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerImpl.java
@@ -0,0 +1,527 @@
+// 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.chrome.browser.price_tracking;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.VisibleForTesting;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import org.chromium.base.Callback;
+import org.chromium.base.ContextUtils;
+import org.chromium.base.IntentUtils;
+import org.chromium.base.Log;
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
+import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
+import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
+import org.chromium.chrome.browser.notifications.NotificationIntentInterceptor;
+import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
+import org.chromium.chrome.browser.notifications.NotificationUmaTracker.SystemNotificationType;
+import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.subscriptions.CommerceSubscription;
+import org.chromium.chrome.browser.subscriptions.CommerceSubscription.CommerceSubscriptionType;
+import org.chromium.chrome.browser.subscriptions.CommerceSubscription.SubscriptionManagementType;
+import org.chromium.chrome.browser.subscriptions.CommerceSubscription.TrackingIdType;
+import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceFactory;
+import org.chromium.chrome.browser.subscriptions.SubscriptionsManager;
+import org.chromium.chrome.browser.subscriptions.SubscriptionsManagerImpl;
+import org.chromium.components.browser_ui.notifications.NotificationManagerProxy;
+import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl;
+import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer;
+
+import java.util.Locale;
+
+/**
+ * Manage price drop notifications.
+ */
+public class PriceDropNotificationManagerImpl implements PriceDropNotificationManager {
+    private static final String TAG = "PriceDropNotif";
+    private static final String ACTION_APP_NOTIFICATION_SETTINGS =
+            "android.settings.APP_NOTIFICATION_SETTINGS";
+    private static final String EXTRA_APP_PACKAGE = "app_package";
+    private static final String EXTRA_APP_UID = "app_uid";
+    // The action ids should be the same as defined in the server, see {@link
+    // HandleProductUpdateEventsProducerModule}.
+    static final String ACTION_ID_VISIT_SITE = "visit_site";
+    static final String ACTION_ID_TURN_OFF_ALERT = "turn_off_alert";
+
+    static final String EXTRA_DESTINATION_URL =
+            "org.chromium.chrome.browser.price_tracking.DESTINATION_URL";
+    static final String EXTRA_ACTION_ID = "org.chromium.chrome.browser.price_tracking.ACTION_ID";
+    static final String EXTRA_OFFER_ID = "org.chromium.chrome.browser.price_tracking.OFFER_ID";
+    static final String EXTRA_PRODUCT_CLUSTER_ID =
+            "org.chromium.chrome.browser.price_tracking.PRODUCT_CLUSTER_ID";
+    static final String EXTRA_NOTIFICATION_ID =
+            "org.chromium.chrome.browser.price_tracking.NOTIFICATION_ID";
+
+    static final String CHROME_MANAGED_TIMESTAMPS =
+            ChromePreferenceKeys.PRICE_TRACKING_CHROME_MANAGED_NOTIFICATIONS_TIMESTAMPS;
+    static final String USER_MANAGED_TIMESTAMPS =
+            ChromePreferenceKeys.PRICE_TRACKING_USER_MANAGED_NOTIFICATIONS_TIMESTAMPS;
+
+    @VisibleForTesting
+    public static final String NOTIFICATION_ENABLED_HISTOGRAM =
+            "Commerce.PriceDrop.SystemNotificationEnabled";
+    @VisibleForTesting
+    public static final String NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM =
+            "Commerce.PriceDrops.ChromeManaged.NotificationCount";
+    @VisibleForTesting
+    public static final String NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM =
+            "Commerce.PriceDrops.UserManaged.NotificationCount";
+
+    private static NotificationManagerProxy sNotificationManagerForTesting;
+    private static BookmarkBridge sBookmarkBridgeForTesting;
+
+    /**
+     * Used to host click logic for "turn off alert" action intent.
+     */
+    public static class TrampolineActivity extends Activity {
+        @Override
+        protected void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Intent intent = getIntent();
+            String destinationUrl = IntentUtils.safeGetStringExtra(intent, EXTRA_DESTINATION_URL);
+            String actionId = IntentUtils.safeGetStringExtra(intent, EXTRA_ACTION_ID);
+            String offerId = IntentUtils.safeGetStringExtra(intent, EXTRA_OFFER_ID);
+            String clusterId = IntentUtils.safeGetStringExtra(intent, EXTRA_PRODUCT_CLUSTER_ID);
+            int notificationId = IntentUtils.safeGetIntExtra(intent, EXTRA_NOTIFICATION_ID, 0);
+
+            dismissNotification(notificationId);
+
+            if (TextUtils.isEmpty(offerId)) {
+                Log.e(TAG, "No offer id is provided when handling turn off alert action.");
+                finish();
+                return;
+            }
+
+            // Handles "turn off alert" action button click.
+            ChromeBrowserInitializer.getInstance().runNowOrAfterFullBrowserStarted(() -> {
+                PriceDropNotificationManager priceDropNotificationManager =
+                        PriceDropNotificationManagerFactory.create();
+                assert ACTION_ID_TURN_OFF_ALERT.equals(actionId)
+                    : "Currently only turn off alert action uses this activity.";
+                priceDropNotificationManager.onNotificationActionClicked(
+                        actionId, destinationUrl, offerId, clusterId, /*recordMetrics=*/false);
+                // Finish immediately. Could be better to have a callback from shopping backend.
+                finish();
+            });
+        }
+    }
+
+    /**
+     * Used to dismiss the notification after content click or "visit site" action click.
+     */
+    public static class DismissNotificationChromeActivity extends ChromeLauncherActivity {
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            int notificationId = IntentUtils.safeGetIntExtra(getIntent(), EXTRA_NOTIFICATION_ID, 0);
+            dismissNotification(notificationId);
+            super.onCreate(savedInstanceState);
+            finish();
+        }
+    }
+
+    private final Context mContext;
+    private final NotificationManagerProxy mNotificationManager;
+    private final SharedPreferencesManager mPreferencesManager;
+
+    /**
+     * Constructor.
+     * @param context The application context.
+     * @param notificationManagerProxy The {@link NotificationManagerProxy} for sending
+     *         notifications.
+     */
+    public PriceDropNotificationManagerImpl(
+            Context context, NotificationManagerProxy notificationManagerProxy) {
+        mContext = context;
+        mNotificationManager = notificationManagerProxy;
+        mPreferencesManager = SharedPreferencesManager.getInstance();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return PriceTrackingFeatures.getPriceTrackingNotificationsEnabled();
+    }
+
+    @Override
+    public boolean canPostNotification() {
+        if (!areAppNotificationsEnabled()
+                || !PriceTrackingFeatures.isPriceDropNotificationEligible()) {
+            return false;
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            NotificationChannel channel = getNotificationChannel();
+            if (channel == null || channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean canPostNotificationWithMetricsRecorded() {
+        if (!PriceTrackingFeatures.isPriceDropNotificationEligible()) return false;
+        boolean isSystemNotificationEnabled = areAppNotificationsEnabled();
+        RecordHistogram.recordBooleanHistogram(
+                NOTIFICATION_ENABLED_HISTOGRAM, isSystemNotificationEnabled);
+        if (!isSystemNotificationEnabled) return false;
+
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return true;
+
+        NotificationChannel channel = getNotificationChannel();
+        boolean isChannelCreated = channel != null;
+        RecordHistogram.recordBooleanHistogram(
+                "Commerce.PriceDrop.NotificationChannelCreated", isChannelCreated);
+        if (!isChannelCreated) return false;
+        boolean isChannelBlocked = channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
+        RecordHistogram.recordBooleanHistogram(
+                "Commerce.PriceDrop.NotificationChannelBlocked", isChannelBlocked);
+        return !isChannelBlocked;
+    }
+
+    @Override
+    public void onNotificationPosted(@Nullable Notification notification) {
+        NotificationUmaTracker.getInstance().onNotificationShown(
+                NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS, notification);
+    }
+
+    @Override
+    public void onNotificationClicked(String url) {
+        NotificationUmaTracker.getInstance().onNotificationContentClick(
+                NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
+                NotificationIntentInterceptor.INVALID_CREATE_TIME);
+    }
+
+    @Override
+    public void onNotificationActionClicked(
+            String actionId, String url, @Nullable String offerId, boolean recordMetrics) {
+        onNotificationActionClicked(actionId, url, offerId, null, recordMetrics);
+    }
+
+    @Override
+    public void onNotificationActionClicked(String actionId, String url, @Nullable String offerId,
+            @Nullable String clusterId, boolean recordMetrics) {
+        if (actionId.equals(ACTION_ID_VISIT_SITE) && recordMetrics) {
+            NotificationUmaTracker.getInstance().onNotificationActionClick(
+                    NotificationUmaTracker.ActionType.PRICE_DROP_VISIT_SITE,
+                    NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
+                    NotificationIntentInterceptor.INVALID_CREATE_TIME);
+        } else if (actionId.equals(ACTION_ID_TURN_OFF_ALERT)) {
+            if (offerId == null && clusterId == null) return;
+            SubscriptionsManagerImpl subscriptionsManager =
+                    (new CommerceSubscriptionsServiceFactory())
+                            .getForLastUsedProfile()
+                            .getSubscriptionsManager();
+            Callback<Integer> callback = (status) -> {
+                assert status
+                        == SubscriptionsManager.StatusCode.OK : "Failed to remove subscriptions.";
+                Log.e(TAG,
+                        String.format(
+                                Locale.US, "Failed to remove subscriptions. Status: %d", status));
+            };
+            final BookmarkBridge bookmarkBridge;
+            if (sBookmarkBridgeForTesting != null) {
+                bookmarkBridge = sBookmarkBridgeForTesting;
+            } else {
+                bookmarkBridge = new BookmarkBridge(Profile.getLastUsedRegularProfile());
+            }
+
+            Runnable unsubscribeRunnable = () -> {
+                if (offerId != null) {
+                    subscriptionsManager.unsubscribe(
+                            new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK, offerId,
+                                    SubscriptionManagementType.CHROME_MANAGED,
+                                    TrackingIdType.OFFER_ID),
+                            callback);
+                }
+                if (clusterId != null) {
+                    subscriptionsManager.unsubscribe(
+                            new CommerceSubscription(CommerceSubscriptionType.PRICE_TRACK,
+                                    clusterId, SubscriptionManagementType.USER_MANAGED,
+                                    TrackingIdType.PRODUCT_CLUSTER_ID),
+                            callback);
+                }
+            };
+
+            // Only attempt to unsubscribe once the corresponding bookmarks can also be updated.
+            if (bookmarkBridge.isBookmarkModelLoaded()) {
+                unsubscribeRunnable.run();
+            } else {
+                bookmarkBridge.addObserver(new BookmarkBridge.BookmarkModelObserver() {
+                    @Override
+                    public void bookmarkModelLoaded() {
+                        unsubscribeRunnable.run();
+                        bookmarkBridge.removeObserver(this);
+                    }
+
+                    @Override
+                    public void bookmarkModelChanged() {}
+                });
+            }
+
+            if (recordMetrics) {
+                NotificationUmaTracker.getInstance().onNotificationActionClick(
+                        NotificationUmaTracker.ActionType.PRICE_DROP_TURN_OFF_ALERT,
+                        NotificationUmaTracker.SystemNotificationType.PRICE_DROP_ALERTS,
+                        NotificationIntentInterceptor.INVALID_CREATE_TIME);
+            }
+        }
+    }
+
+    @Override
+    @Deprecated
+    public Intent getNotificationClickIntent(String url) {
+        return getNotificationClickIntent(url, 0);
+    }
+
+    @Override
+    public Intent getNotificationClickIntent(String url, int notificationId) {
+        Intent intent =
+                new Intent()
+                        .setAction(Intent.ACTION_VIEW)
+                        .setData(Uri.parse(url))
+                        .setClass(mContext, DismissNotificationChromeActivity.class)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
+                        .putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName())
+                        .putExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true)
+                        .putExtra(EXTRA_NOTIFICATION_ID, notificationId);
+        IntentUtils.addTrustedIntentExtras(intent);
+        return intent;
+    }
+
+    @Override
+    @Deprecated
+    public Intent getNotificationActionClickIntent(String actionId, String url, String offerId) {
+        return getNotificationActionClickIntent(actionId, url, offerId, null, 0);
+    }
+
+    @Override
+    @Deprecated
+    public Intent getNotificationActionClickIntent(
+            String actionId, String url, String offerId, String clusterId) {
+        return getNotificationActionClickIntent(actionId, url, offerId, clusterId, 0);
+    }
+
+    @Override
+    public Intent getNotificationActionClickIntent(
+            String actionId, String url, String offerId, String clusterId, int notificationId) {
+        if (ACTION_ID_VISIT_SITE.equals(actionId)) {
+            return getNotificationClickIntent(url, notificationId);
+        }
+        if (ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
+            Intent intent = new Intent(mContext, TrampolineActivity.class);
+            intent.putExtra(EXTRA_DESTINATION_URL, url);
+            intent.putExtra(EXTRA_ACTION_ID, actionId);
+            intent.putExtra(EXTRA_OFFER_ID, offerId);
+            if (clusterId != null) intent.putExtra(EXTRA_PRODUCT_CLUSTER_ID, clusterId);
+            intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId);
+            IntentUtils.addTrustedIntentExtras(intent);
+            return intent;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean areAppNotificationsEnabled() {
+        if (sNotificationManagerForTesting != null) {
+            return sNotificationManagerForTesting.areNotificationsEnabled();
+        }
+        return mNotificationManager.areNotificationsEnabled();
+    }
+
+    @Override
+    @RequiresApi(Build.VERSION_CODES.O)
+    public void createNotificationChannel() {
+        NotificationChannel channel = getNotificationChannel();
+        if (channel != null) return;
+        new ChannelsInitializer(mNotificationManager, ChromeChannelDefinitions.getInstance(),
+                mContext.getResources())
+                .ensureInitialized(ChromeChannelDefinitions.ChannelId.PRICE_DROP);
+    }
+
+    @Override
+    public void launchNotificationSettings() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            // Make sure the channel is initialized before sending users to the settings.
+            createNotificationChannel();
+        }
+        mContext.startActivity(getNotificationSettingsIntent());
+        // Disable PriceAlertsMessageCard after the first time we send users to notification
+        // settings.
+        PriceTrackingUtilities.disablePriceAlertsMessageCard();
+    }
+
+    @Override
+    @VisibleForTesting
+    public Intent getNotificationSettingsIntent() {
+        Intent intent = new Intent();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            if (areAppNotificationsEnabled()) {
+                intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
+                intent.putExtra(Settings.EXTRA_APP_PACKAGE, mContext.getPackageName());
+                intent.putExtra(
+                        Settings.EXTRA_CHANNEL_ID, ChromeChannelDefinitions.ChannelId.PRICE_DROP);
+            } else {
+                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+                intent.putExtra(Settings.EXTRA_APP_PACKAGE, mContext.getPackageName());
+            }
+        } else {
+            intent.setAction(ACTION_APP_NOTIFICATION_SETTINGS);
+            intent.putExtra(EXTRA_APP_PACKAGE, mContext.getPackageName());
+            intent.putExtra(EXTRA_APP_UID, mContext.getApplicationInfo().uid);
+        }
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+
+    @Override
+    @VisibleForTesting
+    @RequiresApi(Build.VERSION_CODES.O)
+    public NotificationChannel getNotificationChannel() {
+        return mNotificationManager.getNotificationChannel(
+                ChromeChannelDefinitions.ChannelId.PRICE_DROP);
+    }
+
+    /**
+     * Set notificationManager for testing.
+     *
+     * @param notificationManager that will be set.
+     */
+    @VisibleForTesting
+    public static void setNotificationManagerForTesting(
+            NotificationManagerProxy notificationManager) {
+        sNotificationManagerForTesting = notificationManager;
+    }
+
+    /**
+     * Set a mock BookmarkBridge for testing so we don't need to access Profile.
+     *
+     * @param bookmarkBridge The bookmark bridge to use.
+     */
+    @VisibleForTesting
+    public static void setBookmarkBridgeForTesting(BookmarkBridge bookmarkBridge) {
+        sBookmarkBridgeForTesting = bookmarkBridge;
+    }
+
+    /**
+     * Delete price drop notification channel for testing.
+     */
+    @Override
+    @VisibleForTesting
+    @RequiresApi(Build.VERSION_CODES.O)
+    public void deleteChannelForTesting() {
+        mNotificationManager.deleteNotificationChannel(
+                ChromeChannelDefinitions.ChannelId.PRICE_DROP);
+    }
+
+    @Override
+    public void recordMetricsForNotificationCounts() {
+        RecordHistogram.recordCount100Histogram(NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM,
+                updateNotificationTimestamps(
+                        SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED, false));
+        RecordHistogram.recordCount100Histogram(NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM,
+                updateNotificationTimestamps(
+                        SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED, false));
+    }
+
+    @Override
+    public boolean hasReachedMaxAllowedNotificationNumber(@SystemNotificationType int type) {
+        boolean hasReached = updateNotificationTimestamps(type, false)
+                >= PriceTrackingNotificationConfig.getMaxAllowedNotificationNumber(type);
+        String managementType = notificationTypeToManagementType(type);
+        if (managementType != null) {
+            RecordHistogram.recordBooleanHistogram(
+                    String.format(Locale.US, "Commerce.PriceDrops.%s.NotificationReachedCap",
+                            managementType),
+                    hasReached);
+        }
+        return hasReached;
+    }
+
+    @Override
+    public int updateNotificationTimestamps(
+            @SystemNotificationType int type, boolean attachCurrentTime) {
+        long currentTime = System.currentTimeMillis();
+        JSONArray newTimestamps = new JSONArray();
+        try {
+            String oldSerializedTimestamps = getStoredNotificationTimestamps(type);
+            JSONArray oldTimestamps = new JSONArray(oldSerializedTimestamps);
+            for (int i = 0; i < oldTimestamps.length(); i++) {
+                long timestamp = oldTimestamps.getLong(i);
+                if (currentTime - timestamp > PriceTrackingNotificationConfig
+                                                      .getNotificationTimestampsStoreWindowMs()) {
+                    continue;
+                }
+                newTimestamps.put(timestamp);
+            }
+        } catch (JSONException e) {
+            Log.e(TAG,
+                    String.format(Locale.US, "Failed to parse notification timestamps. Details: %s",
+                            e.getMessage()));
+            // If one parse fails, we discard all data and reset the stored timestamps.
+            newTimestamps = new JSONArray();
+        }
+        if (attachCurrentTime) newTimestamps.put(currentTime);
+        writeSerializedNotificationTimestamps(type, newTimestamps.toString());
+        return newTimestamps.length();
+    }
+
+    private String getStoredNotificationTimestamps(@SystemNotificationType int type) {
+        String serializedTimestamps = "";
+        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
+            serializedTimestamps = mPreferencesManager.readString(CHROME_MANAGED_TIMESTAMPS, "");
+        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
+            serializedTimestamps = mPreferencesManager.readString(USER_MANAGED_TIMESTAMPS, "");
+        }
+        return serializedTimestamps;
+    }
+
+    private void writeSerializedNotificationTimestamps(
+            @SystemNotificationType int type, String serializedTimestamps) {
+        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
+            mPreferencesManager.writeString(CHROME_MANAGED_TIMESTAMPS, serializedTimestamps);
+        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
+            mPreferencesManager.writeString(USER_MANAGED_TIMESTAMPS, serializedTimestamps);
+        }
+    }
+
+    private String notificationTypeToManagementType(@SystemNotificationType int type) {
+        if (type == SystemNotificationType.PRICE_DROP_ALERTS_CHROME_MANAGED) {
+            return "ChromeManaged";
+        } else if (type == SystemNotificationType.PRICE_DROP_ALERTS_USER_MANAGED) {
+            return "UserManaged";
+        } else {
+            Log.e(TAG, "Invalid notification type.");
+            return null;
+        }
+    }
+
+    private static void dismissNotification(int notificationId) {
+        new NotificationManagerProxyImpl(ContextUtils.getApplicationContext())
+                .cancel(PriceDropNotifier.NOTIFICATION_TAG, notificationId);
+    }
+}
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java
index b0cbd42c..25688a6a 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java
@@ -197,10 +197,10 @@
     }
 
     private static @NotificationUmaTracker.ActionType int actionIdToUmaActionType(String actionId) {
-        if (PriceDropNotificationManager.ACTION_ID_VISIT_SITE.equals(actionId)) {
+        if (PriceDropNotificationManagerImpl.ACTION_ID_VISIT_SITE.equals(actionId)) {
             return ActionType.PRICE_DROP_VISIT_SITE;
         }
-        if (PriceDropNotificationManager.ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
+        if (PriceDropNotificationManagerImpl.ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
             return ActionType.PRICE_DROP_TURN_OFF_ALERT;
         }
         return ActionType.UNKNOWN;
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java
index c5aec19..d9bdf70e 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java
@@ -216,9 +216,9 @@
     private static @Nullable String getActionText(String actionId) {
         if (TextUtils.isEmpty(actionId)) return null;
         Context context = ContextUtils.getApplicationContext();
-        if (PriceDropNotificationManager.ACTION_ID_VISIT_SITE.equals(actionId)) {
+        if (PriceDropNotificationManagerImpl.ACTION_ID_VISIT_SITE.equals(actionId)) {
             return context.getString(R.string.price_drop_notification_action_visit_site);
-        } else if (PriceDropNotificationManager.ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
+        } else if (PriceDropNotificationManagerImpl.ACTION_ID_TURN_OFF_ALERT.equals(actionId)) {
             return context.getString(R.string.price_drop_notification_action_turn_off_alert);
         }
         return null;
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingUtilities.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingUtilities.java
index ace2080b..947dfd73 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingUtilities.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingUtilities.java
@@ -6,9 +6,10 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.base.FeatureList;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.subscriptions.CommerceSubscriptionsServiceConfig;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 
 /** Utility class for price tracking. */
@@ -28,6 +29,11 @@
     public static final String PRICE_ALERTS_MESSAGE_CARD_SHOW_COUNT =
             ChromePreferenceKeys.PRICE_TRACKING_PRICE_ALERTS_MESSAGE_CARD_SHOW_COUNT;
 
+    // TODO(zhiyuancai): Dedup from CommerceSubscriptionsServiceConfig.java.
+    @VisibleForTesting
+    public static final String IMPLICIT_SUBSCRIPTIONS_ENABLED_PARAM =
+            "implicit_subscriptions_enabled";
+
     @VisibleForTesting
     public static final SharedPreferencesManager SHARED_PREFERENCES_MANAGER =
             SharedPreferencesManager.getInstance();
@@ -102,7 +108,7 @@
      */
     public static boolean isPriceAlertsMessageCardEnabled() {
         return PriceTrackingFeatures.isPriceDropNotificationEligible()
-                && CommerceSubscriptionsServiceConfig.isImplicitSubscriptionsEnabled()
+                && isImplicitSubscriptionsEnabled()
                 && SHARED_PREFERENCES_MANAGER.readBoolean(
                         PRICE_ALERTS_MESSAGE_CARD, PriceTrackingFeatures.isPriceTrackingEnabled());
     }
@@ -147,4 +153,13 @@
     public static boolean shouldShowPriceTrackingMenu() {
         return false;
     }
+
+    private static boolean isImplicitSubscriptionsEnabled() {
+        if (FeatureList.isInitialized()) {
+            return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                    ChromeFeatureList.COMMERCE_PRICE_TRACKING, IMPLICIT_SUBSCRIPTIONS_ENABLED_PARAM,
+                    false);
+        }
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/chrome/browser/commerce/price_tracking/android/java_sources.gni b/chrome/browser/commerce/price_tracking/android/java_sources.gni
index 539dd4c..4afb3981 100644
--- a/chrome/browser/commerce/price_tracking/android/java_sources.gni
+++ b/chrome/browser/commerce/price_tracking/android/java_sources.gni
@@ -3,10 +3,13 @@
 # found in the LICENSE file.
 
 price_tracking_java_sources = [
-  "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManager.java",
   "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerFactory.java",
+  "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerImpl.java",
   "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifier.java",
   "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonController.java",
   "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationBridge.java",
   "//chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingNotificationConfig.java",
 ]
+
+price_tracking_java_deps =
+    [ "//chrome/browser/commerce/price_tracking/android:public_java" ]
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java
index 5db25fe..b107f5f 100644
--- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java
+++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotificationManagerTest.java
@@ -47,7 +47,7 @@
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker.SystemNotificationType;
 import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager.DismissNotificationChromeActivity;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl.DismissNotificationChromeActivity;
 import org.chromium.chrome.browser.subscriptions.CommerceSubscription;
 import org.chromium.chrome.browser.subscriptions.CommerceSubscription.CommerceSubscriptionType;
 import org.chromium.chrome.browser.subscriptions.CommerceSubscription.SubscriptionManagementType;
@@ -110,10 +110,10 @@
     @Before
     public void setUp() {
         mMockNotificationManager = new MockNotificationManagerProxy();
-        PriceDropNotificationManager.setNotificationManagerForTesting(mMockNotificationManager);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(mMockNotificationManager);
         mPriceDropNotificationManager = PriceDropNotificationManagerFactory.create();
         when(mMockBookmarkBridge.isBookmarkModelLoaded()).thenReturn(true);
-        PriceDropNotificationManager.setBookmarkBridgeForTesting(mMockBookmarkBridge);
+        PriceDropNotificationManagerImpl.setBookmarkBridgeForTesting(mMockBookmarkBridge);
     }
 
     @After
@@ -121,7 +121,7 @@
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             mPriceDropNotificationManager.deleteChannelForTesting();
         }
-        PriceDropNotificationManager.setNotificationManagerForTesting(null);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(null);
     }
 
     private void verifyClickIntent(Intent intent) {
@@ -136,7 +136,7 @@
         assertEquals(true,
                 intent.getBooleanExtra(WebappConstants.REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, false));
         assertEquals(NOTIFICATION_ID,
-                intent.getIntExtra(PriceDropNotificationManager.EXTRA_NOTIFICATION_ID, 0));
+                intent.getIntExtra(PriceDropNotificationManagerImpl.EXTRA_NOTIFICATION_ID, 0));
     }
 
     @Test
@@ -240,23 +240,23 @@
         Intent turnOffAlertIntent = mPriceDropNotificationManager.getNotificationActionClickIntent(
                 ACTION_ID_TURN_OFF_ALERT, TEST_URL, OFFER_ID, PRODUCT_CLUSTER_ID, NOTIFICATION_ID);
         assertNotNull(turnOffAlertIntent);
-        assertEquals(PriceDropNotificationManager.TrampolineActivity.class.getName(),
+        assertEquals(PriceDropNotificationManagerImpl.TrampolineActivity.class.getName(),
                 turnOffAlertIntent.getComponent().getClassName());
         assertEquals(PRODUCT_CLUSTER_ID,
-                IntentUtils.safeGetStringExtra(
-                        turnOffAlertIntent, PriceDropNotificationManager.EXTRA_PRODUCT_CLUSTER_ID));
+                IntentUtils.safeGetStringExtra(turnOffAlertIntent,
+                        PriceDropNotificationManagerImpl.EXTRA_PRODUCT_CLUSTER_ID));
         assertEquals(OFFER_ID,
                 IntentUtils.safeGetStringExtra(
-                        turnOffAlertIntent, PriceDropNotificationManager.EXTRA_OFFER_ID));
+                        turnOffAlertIntent, PriceDropNotificationManagerImpl.EXTRA_OFFER_ID));
         assertEquals(TEST_URL,
-                IntentUtils.safeGetStringExtra(
-                        turnOffAlertIntent, PriceDropNotificationManager.EXTRA_DESTINATION_URL));
+                IntentUtils.safeGetStringExtra(turnOffAlertIntent,
+                        PriceDropNotificationManagerImpl.EXTRA_DESTINATION_URL));
         assertEquals(ACTION_ID_TURN_OFF_ALERT,
                 IntentUtils.safeGetStringExtra(
-                        turnOffAlertIntent, PriceDropNotificationManager.EXTRA_ACTION_ID));
+                        turnOffAlertIntent, PriceDropNotificationManagerImpl.EXTRA_ACTION_ID));
         assertEquals(NOTIFICATION_ID,
-                IntentUtils.safeGetIntExtra(
-                        turnOffAlertIntent, PriceDropNotificationManager.EXTRA_NOTIFICATION_ID, 0));
+                IntentUtils.safeGetIntExtra(turnOffAlertIntent,
+                        PriceDropNotificationManagerImpl.EXTRA_NOTIFICATION_ID, 0));
     }
 
     @Test
@@ -300,7 +300,7 @@
         JSONArray jsonArray = new JSONArray();
         jsonArray.put(mockTimestamp);
         preferencesManager.writeString(
-                PriceDropNotificationManager.USER_MANAGED_TIMESTAMPS, jsonArray.toString());
+                PriceDropNotificationManagerImpl.USER_MANAGED_TIMESTAMPS, jsonArray.toString());
         assertEquals(
                 0, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, false));
 
@@ -308,14 +308,15 @@
         jsonArray = new JSONArray();
         jsonArray.put(mockTimestamp);
         preferencesManager.writeString(
-                PriceDropNotificationManager.USER_MANAGED_TIMESTAMPS, jsonArray.toString());
+                PriceDropNotificationManagerImpl.USER_MANAGED_TIMESTAMPS, jsonArray.toString());
         assertEquals(
                 1, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, false));
 
         assertEquals(2, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, true));
         assertEquals(3, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, true));
 
-        preferencesManager.writeString(PriceDropNotificationManager.USER_MANAGED_TIMESTAMPS, "");
+        preferencesManager.writeString(
+                PriceDropNotificationManagerImpl.USER_MANAGED_TIMESTAMPS, "");
         assertEquals(
                 0, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, false));
         assertEquals(1, mPriceDropNotificationManager.updateNotificationTimestamps(mockType, true));
diff --git a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java
index 4fd63d67..7dba11a 100644
--- a/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java
+++ b/chrome/browser/commerce/price_tracking/android/javatests/src/org/chromium/chrome/browser/price_tracking/PriceDropNotifierUnitTest.java
@@ -139,10 +139,10 @@
 
     private void showNotification() {
         List<ActionData> actionDataList = new ArrayList<>();
-        actionDataList.add(
-                new ActionData(PriceDropNotificationManager.ACTION_ID_VISIT_SITE, ACTION_TEXT_0));
         actionDataList.add(new ActionData(
-                PriceDropNotificationManager.ACTION_ID_TURN_OFF_ALERT, ACTION_TEXT_1));
+                PriceDropNotificationManagerImpl.ACTION_ID_VISIT_SITE, ACTION_TEXT_0));
+        actionDataList.add(new ActionData(
+                PriceDropNotificationManagerImpl.ACTION_ID_TURN_OFF_ALERT, ACTION_TEXT_1));
         showNotification(actionDataList);
     }
 
@@ -161,7 +161,7 @@
         // Simulate to send a PendingIntent by manually starting the TrampolineActivity.
         ShadowPendingIntent shadowPendingIntent = Shadows.shadowOf(pendingIntent);
         Robolectric
-                .buildActivity(PriceDropNotificationManager.TrampolineActivity.class,
+                .buildActivity(PriceDropNotificationManagerImpl.TrampolineActivity.class,
                         shadowPendingIntent.getSavedIntent())
                 .create();
     }
diff --git a/chrome/browser/commerce/subscriptions/android/BUILD.gn b/chrome/browser/commerce/subscriptions/android/BUILD.gn
index d2b163d..ee3ac873 100644
--- a/chrome/browser/commerce/subscriptions/android/BUILD.gn
+++ b/chrome/browser/commerce/subscriptions/android/BUILD.gn
@@ -12,11 +12,40 @@
 }
 
 android_library("java") {
-  sources = [ "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java" ]
+  sources = [
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionJsonSerializer.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsMetrics.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceConfig.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceProxy.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsStorage.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java",
+    "java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java",
+  ]
 
   deps = [
     "//base:base_java",
+    "//base:jni_java",
+    "//build/android:build_java",
+    "//chrome/browser/android/lifecycle:java",
+    "//chrome/browser/commerce/price_tracking/android:public_java",
+    "//chrome/browser/endpoint_fetcher:java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/preferences:java",
+    "//chrome/browser/profiles/android:java",
+    "//chrome/browser/signin/services/android:java",
+    "//chrome/browser/tab:java",
+    "//chrome/browser/tabmodel:java",
+    "//components/prefs/android:java",
+    "//components/signin/public/android:java",
+    "//components/user_prefs/android:java",
+    "//content/public/android:content_full_java",
+    "//net/android:net_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
+    "//url:gurl_java",
   ]
+
+  annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 }
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java
index 17a8264..34017bbe 100644
--- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java
+++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java
@@ -11,7 +11,6 @@
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
-import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
 import org.chromium.chrome.browser.subscriptions.CommerceSubscription.CommerceSubscriptionType;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
@@ -39,8 +38,9 @@
     private PauseResumeWithNativeObserver mPauseResumeWithNativeObserver;
 
     /** Creates a new instance. */
-    CommerceSubscriptionsService(
-            SubscriptionsManagerImpl subscriptionsManager, IdentityManager identityManager) {
+    CommerceSubscriptionsService(SubscriptionsManagerImpl subscriptionsManager,
+            IdentityManager identityManager,
+            PriceDropNotificationManager priceDropNotificationManager) {
         mSubscriptionManager = subscriptionsManager;
         mIdentityManager = identityManager;
         mIdentityManagerObserver = new IdentityManager.Observer() {
@@ -51,7 +51,7 @@
         };
         mIdentityManager.addObserver(mIdentityManagerObserver);
         mSharedPreferencesManager = SharedPreferencesManager.getInstance();
-        mPriceDropNotificationManager = PriceDropNotificationManagerFactory.create();
+        mPriceDropNotificationManager = priceDropNotificationManager;
         mMetrics = new CommerceSubscriptionsMetrics();
     }
 
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java
index ac923a9..09124c6 100644
--- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java
+++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java
@@ -6,6 +6,8 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileManager;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
@@ -62,8 +64,12 @@
         Profile profile = Profile.getLastUsedRegularProfile();
         CommerceSubscriptionsService service = sProfileToSubscriptionsService.get(profile);
         if (service == null) {
-            service = new CommerceSubscriptionsService(new SubscriptionsManagerImpl(profile),
-                    IdentityServicesProvider.get().getIdentityManager(profile));
+            PriceDropNotificationManager priceDropNotificationManager =
+                    PriceDropNotificationManagerFactory.create();
+            service = new CommerceSubscriptionsService(
+                    new SubscriptionsManagerImpl(profile, priceDropNotificationManager),
+                    IdentityServicesProvider.get().getIdentityManager(profile),
+                    priceDropNotificationManager);
             sProfileToSubscriptionsService.put(profile, service);
         }
         return service;
diff --git a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java
index 0e662047..8eba7bb 100644
--- a/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java
+++ b/chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java
@@ -11,7 +11,7 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.ObserverList;
-import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
 import org.chromium.chrome.browser.profiles.Profile;
 
@@ -43,6 +43,7 @@
     private boolean mCanHandleRequests;
     private Queue<DeferredSubscriptionOperation> mDeferredTasks;
     private final ObserverList<SubscriptionObserver> mObservers;
+    private final PriceDropNotificationManager mPriceDropNotificationManager;
 
     private static class DeferredSubscriptionOperation {
         private final @Operation int mOperation;
@@ -69,16 +70,19 @@
         }
     }
 
-    public SubscriptionsManagerImpl(Profile profile) {
+    public SubscriptionsManagerImpl(
+            Profile profile, PriceDropNotificationManager priceDropNotificationManager) {
         this(profile, new CommerceSubscriptionsStorage(profile),
-                new CommerceSubscriptionsServiceProxy(profile));
+                new CommerceSubscriptionsServiceProxy(profile), priceDropNotificationManager);
     }
 
     @VisibleForTesting
     SubscriptionsManagerImpl(Profile profile, CommerceSubscriptionsStorage storage,
-            CommerceSubscriptionsServiceProxy proxy) {
+            CommerceSubscriptionsServiceProxy proxy,
+            PriceDropNotificationManager priceDropNotificationManager) {
         mStorage = storage;
         mServiceProxy = proxy;
+        mPriceDropNotificationManager = priceDropNotificationManager;
         mDeferredTasks = new LinkedList<>();
         mCanHandleRequests = false;
         initTypes(this::onInitComplete);
@@ -148,7 +152,7 @@
                 && CommerceSubscription.SubscriptionManagementType.USER_MANAGED.equals(
                         subscriptions.get(0).getManagementType())
                 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            (PriceDropNotificationManagerFactory.create()).createNotificationChannel();
+            mPriceDropNotificationManager.createNotificationChannel();
         }
 
         if (!mCanHandleRequests) {
@@ -431,4 +435,4 @@
     public void setCanHandlerequests(boolean value) {
         mCanHandleRequests = value;
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/commerce/subscriptions/android/java_sources.gni b/chrome/browser/commerce/subscriptions/android/java_sources.gni
index dc262ae..53a1fc8 100644
--- a/chrome/browser/commerce/subscriptions/android/java_sources.gni
+++ b/chrome/browser/commerce/subscriptions/android/java_sources.gni
@@ -4,29 +4,10 @@
 
 # TODO(crbug/1210158): This should be a separate build target when circular
 # dependencies are removed.
-commerce_subscriptions_java_sources = [
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscription.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionJsonSerializer.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsMetrics.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsService.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceProxy.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsStorage.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/ImplicitPriceDropSubscriptionsManager.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManager.java",
-  "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImpl.java",
-]
+commerce_subscriptions_java_sources = [ "//chrome/browser/commerce/subscriptions/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceFactory.java" ]
 
 commerce_subscriptions_java_deps = [
   "//base:base_java",
-  "//base:jni_java",
-  "//chrome/android:base_module_java",
-  "//chrome/browser/android/lifecycle:java",
-  "//chrome/browser/endpoint_fetcher:java",
-  "//chrome/browser/flags:java",
-  "//chrome/browser/preferences:java",
   "//chrome/browser/profiles/android:java",
-  "//chrome/browser/tab:java",
-  "//chrome/browser/tabmodel:java",
-  "//url:gurl_java",
+  "//chrome/browser/signin/services/android:java",
 ]
diff --git a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java
index 81d05273..0fd2eb6 100644
--- a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java
+++ b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java
@@ -42,6 +42,8 @@
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
@@ -103,6 +105,7 @@
     private CommerceSubscriptionsService mService;
     private SharedPreferencesManager mSharedPreferencesManager;
     private MockNotificationManagerProxy mMockNotificationManager;
+    private PriceDropNotificationManager mPriceDropNotificationManager;
     private FeatureList.TestValues mTestValues;
 
     @Before
@@ -128,7 +131,7 @@
 
         mMockNotificationManager = new MockNotificationManagerProxy();
         mMockNotificationManager.setNotificationsEnabled(false);
-        PriceDropNotificationManager.setNotificationManagerForTesting(mMockNotificationManager);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(mMockNotificationManager);
 
         mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mUserPrefsJni);
         Profile.setLastUsedProfileForTesting(mProfile);
@@ -136,14 +139,16 @@
         IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider);
         when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager);
 
-        mService = new CommerceSubscriptionsService(mSubscriptionsManager, mIdentityManager);
+        mPriceDropNotificationManager = PriceDropNotificationManagerFactory.create();
+        mService = new CommerceSubscriptionsService(
+                mSubscriptionsManager, mIdentityManager, mPriceDropNotificationManager);
         verify(mIdentityManager, times(1)).addObserver(mIdentityManagerObserverCaptor.capture());
         mService.setImplicitSubscriptionsManagerForTesting(mImplicitSubscriptionsManager);
     }
 
     @After
     public void tearDown() {
-        PriceDropNotificationManager.setNotificationManagerForTesting(null);
+        PriceDropNotificationManagerImpl.setNotificationManagerForTesting(null);
     }
 
     @Test
@@ -182,14 +187,15 @@
     public void testOnResume() {
         setupTestOnResume();
         assertThat(RecordHistogram.getHistogramTotalCountForTesting(
-                           PriceDropNotificationManager.NOTIFICATION_ENABLED_HISTOGRAM),
+                           PriceDropNotificationManagerImpl.NOTIFICATION_ENABLED_HISTOGRAM),
+                equalTo(1));
+        assertThat(RecordHistogram.getHistogramTotalCountForTesting(
+                           PriceDropNotificationManagerImpl
+                                   .NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM),
                 equalTo(1));
         assertThat(
                 RecordHistogram.getHistogramTotalCountForTesting(
-                        PriceDropNotificationManager.NOTIFICATION_CHROME_MANAGED_COUNT_HISTOGRAM),
-                equalTo(1));
-        assertThat(RecordHistogram.getHistogramTotalCountForTesting(
-                           PriceDropNotificationManager.NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM),
+                        PriceDropNotificationManagerImpl.NOTIFICATION_USER_MANAGED_COUNT_HISTOGRAM),
                 equalTo(1));
         verify(mSubscriptionsManager, times(1))
                 .getSubscriptions(eq(CommerceSubscriptionType.PRICE_TRACK), eq(false),
@@ -233,7 +239,7 @@
 
         setupTestOnResume();
         assertThat(RecordHistogram.getHistogramTotalCountForTesting(
-                           PriceDropNotificationManager.NOTIFICATION_ENABLED_HISTOGRAM),
+                           PriceDropNotificationManagerImpl.NOTIFICATION_ENABLED_HISTOGRAM),
                 equalTo(0));
         verify(mSubscriptionsManager, times(0)).getSubscriptions(anyString(), anyBoolean(), any());
         verify(mImplicitSubscriptionsManager, times(0)).initializeSubscriptions();
@@ -248,7 +254,7 @@
 
         setupTestOnResume();
         assertThat(RecordHistogram.getHistogramTotalCountForTesting(
-                           PriceDropNotificationManager.NOTIFICATION_ENABLED_HISTOGRAM),
+                           PriceDropNotificationManagerImpl.NOTIFICATION_ENABLED_HISTOGRAM),
                 equalTo(0));
         verify(mSubscriptionsManager, times(0)).getSubscriptions(anyString(), anyBoolean(), any());
         verify(mImplicitSubscriptionsManager, times(0)).initializeSubscriptions();
diff --git a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImplTest.java b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImplTest.java
index 83b04525..2015ad4 100644
--- a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImplTest.java
+++ b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/SubscriptionsManagerImplTest.java
@@ -33,6 +33,8 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManager;
+import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerFactory;
 import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.util.browser.Features;
@@ -95,8 +97,11 @@
         FeatureList.setTestValues(mTestValues);
         PriceTrackingFeatures.setIsSignedInAndSyncEnabledForTesting(true);
 
+        PriceDropNotificationManager priceDropNotificationManager =
+                PriceDropNotificationManagerFactory.create();
         mMocker.mock(CommerceSubscriptionsStorageJni.TEST_HOOKS, mCommerceSubscriptionsStorageJni);
-        mSubscriptionsManager = new SubscriptionsManagerImpl(mProfile, mStorage, mProxy);
+        mSubscriptionsManager = new SubscriptionsManagerImpl(
+                mProfile, mStorage, mProxy, priceDropNotificationManager);
 
         mSubscription1 =
                 new CommerceSubscription(CommerceSubscription.CommerceSubscriptionType.PRICE_TRACK,
diff --git a/chrome/browser/device/BUILD.gn b/chrome/browser/device/BUILD.gn
index 9717bb1..e48f35b 100644
--- a/chrome/browser/device/BUILD.gn
+++ b/chrome/browser/device/BUILD.gn
@@ -21,7 +21,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "android/java/src/org/chromium/chrome/browser/device/DeviceConditionsTest.java",
     "android/java/src/org/chromium/chrome/browser/device/ShadowDeviceConditions.java",
@@ -34,7 +33,6 @@
     "//base/test:test_support_java",
     "//chrome/test/android:chrome_java_unit_test_support",
     "//net/android:net_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/download/android/BUILD.gn b/chrome/browser/download/android/BUILD.gn
index 95733a9c..b7a7a10 100644
--- a/chrome/browser/download/android/BUILD.gn
+++ b/chrome/browser/download/android/BUILD.gn
@@ -190,8 +190,6 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/download/DownloadDialogBridgeUnitTest.java",
     "java/src/org/chromium/chrome/browser/download/DownloadDirectoryProviderUnitTest.java",
@@ -213,7 +211,6 @@
     "//components/offline_items_collection/core:core_java",
     "//components/prefs/android:java",
     "//net/android:net_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
diff --git a/chrome/browser/download/internal/android/BUILD.gn b/chrome/browser/download/internal/android/BUILD.gn
index e6a8654..d327db9 100644
--- a/chrome/browser/download/internal/android/BUILD.gn
+++ b/chrome/browser/download/internal/android/BUILD.gn
@@ -268,7 +268,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/chrome/browser/download/home/filter/DeleteUndoOfflineItemFilterTest.java",
     "java/src/org/chromium/chrome/browser/download/home/filter/FiltersTest.java",
@@ -291,7 +290,6 @@
     "//components/browser_ui/util/android:java",
     "//components/offline_items_collection/core:core_java",
     "//components/url_formatter/android:url_formatter_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/enterprise/util/BUILD.gn b/chrome/browser/enterprise/util/BUILD.gn
index 55b0d2d..b18b8d7c 100644
--- a/chrome/browser/enterprise/util/BUILD.gn
+++ b/chrome/browser/enterprise/util/BUILD.gn
@@ -29,8 +29,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "android/java/src/org/chromium/chrome/browser/enterprise/util/EnterpriseInfoImplTest.java" ]
 
   deps = [
@@ -39,7 +37,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base:jni_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
index 9a769941..b4b9a59 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/ash/crostini/crostini_pref_names.h"
 #include "chrome/browser/ash/crostini/crostini_terminal.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/api/terminal/crostini_startup_status.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -319,7 +320,7 @@
     GetSwitch(params_args, &cmdline, kSwitchCurrentWorkingDir, "");
     std::string startup_id = params_args.GetSwitchValueASCII(kSwitchStartupId);
     container_id_ =
-        std::make_unique<crostini::ContainerId>(vm_name, container_name);
+        std::make_unique<guest_os::GuestId>(vm_name, container_name);
     VLOG(1) << "Starting " << *container_id_
             << ", cmdline=" << cmdline.GetCommandLineString();
 
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.h b/chrome/browser/extensions/api/terminal/terminal_private_api.h
index fe9a262..e835bb6 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.h
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.h
@@ -17,9 +17,9 @@
 
 class PrefChangeRegistrar;
 
-namespace crostini {
-struct ContainerId;
-}  // namespace crostini
+namespace guest_os {
+struct GuestId;
+}  // namespace guest_os
 
 namespace extensions {
 
@@ -96,7 +96,7 @@
                                 const std::string& user_id_hash);
   void RespondOnUIThread(bool success, const std::string& terminal_id);
   std::unique_ptr<CrostiniStartupStatus> startup_status_;
-  std::unique_ptr<crostini::ContainerId> container_id_;
+  std::unique_ptr<guest_os::GuestId> container_id_;
 };
 
 // Opens new vmshell process. Returns the new terminal id.
diff --git a/chrome/browser/extensions/extension_action_runner.cc b/chrome/browser/extensions/extension_action_runner.cc
index ec73d02..28e68a90 100644
--- a/chrome/browser/extensions/extension_action_runner.cc
+++ b/chrome/browser/extensions/extension_action_runner.cc
@@ -98,11 +98,10 @@
           SitePermissionsHelper(Profile::FromBrowserContext(browser_context_))
               .GetSiteAccess(*extension, url));
 
-      // Display the checkbox so the user has the option to always run the
-      // action on this site.
-      bool show_checkbox = true;
+      // Running the action does not update permissions.
+      constexpr bool update_permissions = false;
       ShowBlockedActionBubble(
-          extension, show_checkbox,
+          extension, update_permissions,
           base::BindOnce(&ExtensionActionRunner::OnBlockedActionBubbleClosed,
                          weak_factory_.GetWeakPtr(), extension->id(), url,
                          kExpectedSiteAccess, kExpectedSiteAccess));
@@ -153,13 +152,9 @@
   int blocked_actions = GetBlockedActions(extension->id());
   // Refresh the page if there are pending actions which mandate a refresh.
   if (blocked_actions & kRefreshRequiredActionsMask) {
-    // TODO(devlin): The bubble text should make it clear that permissions are
-    // granted only after the user accepts the refresh.
-    // Since the user already changed site access, don't display the checkbox
-    // to always run on site.
-    bool show_checkbox = false;
+    constexpr bool update_permissions = true;
     ShowBlockedActionBubble(
-        extension, show_checkbox,
+        extension, update_permissions,
         base::BindOnce(&ExtensionActionRunner::OnBlockedActionBubbleClosed,
                        weak_factory_.GetWeakPtr(), extension->id(),
                        web_contents()->GetLastCommittedURL(), current_access,
@@ -367,8 +362,8 @@
 
 void ExtensionActionRunner::ShowBlockedActionBubble(
     const Extension* extension,
-    bool show_checkbox,
-    base::OnceCallback<void(bool)> callback) {
+    bool update_permissions,
+    base::OnceClosure callback) {
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
   ExtensionsContainer* const extensions_container =
       browser ? browser->window()->GetExtensionsContainer() : nullptr;
@@ -380,13 +375,12 @@
   if (accept_bubble_for_testing_.has_value()) {
     if (*accept_bubble_for_testing_) {
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE,
-          base::BindOnce(std::move(callback), bubble_is_checked_for_testing_));
+          FROM_HERE, base::BindOnce(std::move(callback)));
     }
     return;
   }
 
-  ShowBlockedActionDialog(browser, extension->id(), show_checkbox,
+  ShowBlockedActionDialog(browser, extension->id(), update_permissions,
                           std::move(callback));
 }
 
@@ -394,8 +388,7 @@
     const std::string& extension_id,
     const GURL& page_url,
     SitePermissionsHelper::SiteAccess current_access,
-    SitePermissionsHelper::SiteAccess new_access,
-    bool is_checked) {
+    SitePermissionsHelper::SiteAccess new_access) {
   // Blocked action dialog could have only be shown if the extension's action
   // was blocked, which means the current site access must be "on click".
   DCHECK_EQ(current_access, SitePermissionsHelper::SiteAccess::kOnClick);
@@ -410,14 +403,6 @@
   if (!extension)
     return;
 
-  // If the user selected the checkbox, always grant access to this site. Note
-  // that the checkbox should only be visible if the dialog wasn't triggered
-  // after a site access change (which would be evidenced in `new_access`).
-  if (is_checked) {
-    DCHECK_EQ(current_access, new_access);
-    new_access = SitePermissionsHelper::SiteAccess::kOnSite;
-  }
-
   if (current_access != new_access) {
     UpdatePageAccessSettings(extension, current_access, new_access);
   } else {
diff --git a/chrome/browser/extensions/extension_action_runner.h b/chrome/browser/extensions/extension_action_runner.h
index e64e74f..b59c49e 100644
--- a/chrome/browser/extensions/extension_action_runner.h
+++ b/chrome/browser/extensions/extension_action_runner.h
@@ -100,10 +100,6 @@
     accept_bubble_for_testing_ = accept_bubble;
   }
 
-  void bubble_is_checked_for_testing(bool is_checked) {
-    bubble_is_checked_for_testing_ = is_checked;
-  }
-
   void set_observer_for_testing(TestObserver* observer) {
     test_observer_ = observer;
   }
@@ -186,16 +182,15 @@
   // actions for the given |extension|. |callback| is invoked when the bubble is
   // closed.
   void ShowBlockedActionBubble(const Extension* extension,
-                               bool show_checkbox,
-                               base::OnceCallback<void(bool)> callback);
+                               bool update_permissions,
+                               base::OnceClosure callback);
 
   // Called when the blocked actions bubble is closed.
   void OnBlockedActionBubbleClosed(
       const std::string& extension_id,
       const GURL& page_url,
       SitePermissionsHelper::SiteAccess current_access,
-      SitePermissionsHelper::SiteAccess new_access,
-      bool is_checked);
+      SitePermissionsHelper::SiteAccess new_access);
 
   // Handles permission changes necessary for page access modification of the
   // |extension|.
@@ -256,10 +251,6 @@
   // callback.
   absl::optional<bool> accept_bubble_for_testing_;
 
-  // If `accept_bubble_for_testing_` is true, signals whether the checkbox is
-  // checked or not.
-  bool bubble_is_checked_for_testing_{false};
-
   raw_ptr<TestObserver> test_observer_;
 
   base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
diff --git a/chrome/browser/extensions/extension_action_runner_browsertest.cc b/chrome/browser/extensions/extension_action_runner_browsertest.cc
index 51d9464..1adeaa5d 100644
--- a/chrome/browser/extensions/extension_action_runner_browsertest.cc
+++ b/chrome/browser/extensions/extension_action_runner_browsertest.cc
@@ -430,8 +430,8 @@
   SitePermissionsHelper permissions(profile());
   EXPECT_EQ(permissions.GetSiteAccess(*extension, url), SiteAccess::kOnClick);
 
-  // Wire up the runner to reject the blocked action bubble prompting for
-  // page refresh, and run the action.
+  // Run the action without changing permissions, and reject the blocked action
+  // bubble prompting for page refresh.
   runner->accept_bubble_for_testing(false);
   runner->RunAction(extension, true);
   base::RunLoop().RunUntilIdle();
@@ -443,10 +443,9 @@
   EXPECT_FALSE(DidInjectScript(web_contents));
   EXPECT_TRUE(runner->WantsToRun(extension));
 
-  // Wire up the runner to automatically accept the blocked action bubble with
-  // no checkbox marked, and run the action.
+  // Run the action without changing permissions, and accept the blocked action
+  // bubble prompting for page refresh.
   runner->accept_bubble_for_testing(true);
-  runner->bubble_is_checked_for_testing(false);
   runner->RunAction(extension, true);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
@@ -468,17 +467,17 @@
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
   EXPECT_TRUE(runner->WantsToRun(extension));
 
-  // Wire up the runner to automatically accept the blocked action bubble with
-  // the checkbox marked, and run the action.
+  // Request a permission increase, and accept the blocked action bubble
+  // prompting for page refresh.
   runner->accept_bubble_for_testing(true);
-  runner->bubble_is_checked_for_testing(true);
-  runner->RunAction(extension, true);
+  runner->HandlePageAccessModified(extension, SiteAccess::kOnClick,
+                                   SiteAccess::kOnSite);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
 
-  // Since we automatically accepted the bubble (with checkbox selected)
-  // prompting us, the page should have refreshed, the extension should have
-  // injected at document start and the site access should now be "on site".
+  // Since we automatically accepted the bubble prompting us, the page should
+  // have refreshed, the extension should have injected at document start and
+  // the site access should now be "on site".
   EXPECT_GE(web_controller.GetLastCommittedEntry()->GetUniqueID(), nav_id);
   EXPECT_TRUE(DidInjectScript(web_contents));
   EXPECT_FALSE(runner->WantsToRun(extension));
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn
index 69188fc..6946b6d 100644
--- a/chrome/browser/feed/android/BUILD.gn
+++ b/chrome/browser/feed/android/BUILD.gn
@@ -230,10 +230,7 @@
   testonly = true
 
   sources = [
-    "java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java",
     "java/src/org/chromium/chrome/browser/feed/FeedProcessScopeDependencyProviderNativeTest.java",
-    "java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java",
-    "java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java",
     "java/src/org/chromium/chrome/browser/feed/settings/FeedAutoplaySettingsFragmentTest.java",
   ]
 
@@ -276,9 +273,8 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
+    "java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java",
     "java/src/org/chromium/chrome/browser/feed/FakeLinearLayoutManager.java",
     "java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java",
     "java/src/org/chromium/chrome/browser/feed/FeedLoggingParametersTest.java",
@@ -287,8 +283,10 @@
     "java/src/org/chromium/chrome/browser/feed/FeedReliabilityLoggerTest.java",
     "java/src/org/chromium/chrome/browser/feed/FeedSliceViewTrackerTest.java",
     "java/src/org/chromium/chrome/browser/feed/FeedStreamTest.java",
+    "java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java",
     "java/src/org/chromium/chrome/browser/feed/NativeViewListRendererTest.java",
     "java/src/org/chromium/chrome/browser/feed/NtpListContentManagerTest.java",
+    "java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java",
     "java/src/org/chromium/chrome/browser/feed/ScrollTrackerTest.java",
     "java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/feed/feedmanagement/FeedManagementMediatorTest.java",
@@ -343,7 +341,6 @@
     "//third_party/android_deps:espresso_java",
     "//third_party/android_deps:material_design_java",
     "//third_party/android_deps:protobuf_lite_runtime_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java
index d389792..a968ed4 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/BackToTopBubbleScrollListenerTest.java
@@ -4,25 +4,19 @@
 
 package org.chromium.chrome.browser.feed;
 
-import android.support.test.InstrumentationRegistry;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.feature_engagement.Tracker;
 
-/** Tests for {@link BackToTopBubbleScrollListener}. */
-@RunWith(ChromeJUnit4ClassRunner.class)
+/** Unit tests for {@link BackToTopBubbleScrollListener}. */
+@RunWith(BaseRobolectricTestRunner.class)
 public final class BackToTopBubbleScrollListenerTest
         implements FeedBubbleDelegate, BackToTopBubbleScrollListener.ResultHandler {
-    private View mFeedRootView;
     private boolean mIsFeedExpanded;
     private boolean mIsShowingBackToTopBubble;
     private int mHeaderCount;
@@ -103,13 +97,9 @@
     }
 
     @Before
-    public void setUp() {
-        mFeedRootView = new View(InstrumentationRegistry.getContext());
-        mFeedRootView.layout(0, 0, 0, 100);
-    }
+    public void setUp() {}
 
     @Test
-    @SmallTest
     @Feature({"Feed"})
     public void testFeedNotExpanded() {
         mIsFeedExpanded = false;
@@ -129,7 +119,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Feed"})
     public void testNotReachingEndOfFeed() {
         mIsFeedExpanded = true;
@@ -161,7 +150,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Feed"})
     public void testReachingEndOfFeed() {
         mIsFeedExpanded = true;
@@ -204,7 +192,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Feed"})
     public void testNotPassingRequiredNumberOfFeedCards() {
         mIsFeedExpanded = true;
@@ -237,7 +224,6 @@
     }
 
     @Test
-    @SmallTest
     @Feature({"Feed"})
     public void testPassingRequiredNumberOfFeedCards() {
         mIsFeedExpanded = true;
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java
index 1f4d1316..4f3ddb2 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/HeaderIphScrollListenerTest.java
@@ -6,11 +6,8 @@
 
 import static org.mockito.Mockito.when;
 
-import android.support.test.InstrumentationRegistry;
 import android.view.View;
 
-import androidx.test.filters.MediumTest;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -18,13 +15,13 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import org.chromium.base.test.params.BlockJUnit4RunnerDelegate;
 import org.chromium.base.test.params.ParameterAnnotations;
 import org.chromium.base.test.params.ParameterProvider;
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.feed.ScrollListener.ScrollState;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.components.feature_engagement.TriggerState;
@@ -32,9 +29,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/** Tests for {@link HeaderIphScrollListener}. */
+/** Unit test for {@link HeaderIphScrollListener}. */
 @RunWith(ParameterizedRunner.class)
-@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
+@ParameterAnnotations.UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
 public final class HeaderIphScrollListenerTest {
     /** Parameter provider for testing the trigger of the IPH. */
     public static class TestParams implements ParameterProvider {
@@ -97,20 +94,15 @@
 
     @Mock
     private Tracker mTracker;
-    private View mFeedRootView;
 
     private boolean mHasShownMenuIph;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-
-        mFeedRootView = new View(InstrumentationRegistry.getContext());
-        mFeedRootView.layout(0, 0, 0, FEED_VIEW_HEIGHT);
     }
 
     @Test
-    @MediumTest
     @Feature({"Feed"})
     @ParameterAnnotations.UseMethodParameter(TestParamsForOnScroll.class)
     public void onScrollStateChanged_triggerIph(boolean expectEnabled, int scrollState,
@@ -206,7 +198,6 @@
     }
 
     @Test
-    @MediumTest
     @Feature({"Feed"})
     @ParameterAnnotations.UseMethodParameter(TestParamsForOnOffsetChanged.class)
     public void onScrollStateChanged_onHeaderOffsetChanged(boolean expectEnabled, int scrollState,
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java
index 5475396d..7efea7b 100644
--- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java
+++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/RefreshIphScrollListenerTest.java
@@ -6,11 +6,8 @@
 
 import static org.mockito.Mockito.when;
 
-import android.support.test.InstrumentationRegistry;
 import android.view.View;
 
-import androidx.test.filters.MediumTest;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -18,12 +15,12 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import org.chromium.base.test.params.BlockJUnit4RunnerDelegate;
 import org.chromium.base.test.params.ParameterAnnotations;
 import org.chromium.base.test.params.ParameterProvider;
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.components.feature_engagement.FeatureConstants;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.components.feature_engagement.TriggerState;
@@ -31,9 +28,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-/** Tests for {@link RefreshIphScrollListener}. */
+/** Unit test for {@link RefreshIphScrollListener}. */
 @RunWith(ParameterizedRunner.class)
-@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
+@ParameterAnnotations.UseRunnerDelegate(BlockJUnit4RunnerDelegate.class)
 public final class RefreshIphScrollListenerTest {
     /** Parameter provider for testing the trigger of the IPH. */
     public static class TestParams implements ParameterProvider {
@@ -78,20 +75,15 @@
 
     @Mock
     private Tracker mTracker;
-    private View mFeedRootView;
 
     private boolean mHasShownIPH;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-
-        mFeedRootView = new View(InstrumentationRegistry.getContext());
-        mFeedRootView.layout(0, 0, 0, 100);
     }
 
     @Test
-    @MediumTest
     @Feature({"Feed"})
     @ParameterAnnotations.UseMethodParameter(TestParams.class)
     public void triggerIph(boolean expectEnabled, int scrollY, int triggerState,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index ff01e52..087d2a7 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4269,11 +4269,6 @@
     "expiry_milestone": 103
   },
   {
-    "name": "nearby-sharing-receive-wifi-credentials",
-    "owners": [ "crisrael@google.com", "chromeos-cross-device-eng@google.com" ],
-    "expiry_milestone": 103
-  },
-  {
     "name": "nearby-sharing-self-share-auto-accept",
     "owners": [ "hansenmichael@google.com", "chromeos-cross-device-eng@google.com" ],
     "expiry_milestone": 106
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e51bdcc..d4b714a5 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1875,7 +1875,7 @@
 const char kOmniboxSiteSearchStarterPackName[] =
     "Omnibox Site Search Starter Pack";
 const char kOmniboxSiteSearchStarterPackDescription[] =
-    "Enables @history, @bookmarks, and @settings scopes in Omnibox Site "
+    "Enables @history, @bookmarks, and @tabs scopes in Omnibox Site "
     "Search/Keyword Mode";
 const char kOmniboxOnFocusSuggestionsContextualWebAllowSRPName[] =
     "Allow Omnibox contextual web on-focus suggestions on the SRP";
@@ -5287,11 +5287,6 @@
 const char kNearbySharingOnePageOnboardingDescription[] =
     "Enable new One-page onboarding workflow for Nearby Share.";
 
-const char kNearbySharingReceiveWifiCredentialsName[] =
-    "Nearby Sharing Receive WiFi Credentials.";
-const char kNearbySharingReceiveWifiCredentialsDescription[] =
-    "Enables receiving WiFi networks using Nearby Share.";
-
 const char kNearbySharingSelfShareAutoAcceptName[] =
     "Nearby Sharing Self Share Auto-Accept";
 const char kNearbySharingSelfShareAutoAcceptDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index ef09398..0eab04c 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3025,9 +3025,6 @@
 extern const char kNearbySharingOnePageOnboardingName[];
 extern const char kNearbySharingOnePageOnboardingDescription[];
 
-extern const char kNearbySharingReceiveWifiCredentialsName[];
-extern const char kNearbySharingReceiveWifiCredentialsDescription[];
-
 extern const char kNearbySharingSelfShareAutoAcceptName[];
 extern const char kNearbySharingSelfShareAutoAcceptDescription[];
 
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn
index f98f477..b25ea07 100644
--- a/chrome/browser/flags/BUILD.gn
+++ b/chrome/browser/flags/BUILD.gn
@@ -71,7 +71,6 @@
 }
 
 robolectric_library("flags_junit_tests") {
-  testonly = true
   sources = [
     "android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsAnnotationUnitTest.java",
     "android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsSafeModeUnitTest.java",
@@ -89,7 +88,6 @@
     "//base/test:test_support_java",
     "//chrome/browser/preferences:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/incognito/BUILD.gn b/chrome/browser/incognito/BUILD.gn
index d8409525..6662eea 100644
--- a/chrome/browser/incognito/BUILD.gn
+++ b/chrome/browser/incognito/BUILD.gn
@@ -107,8 +107,6 @@
 }
 
 robolectric_library("incognito_junit_tests") {
-  testonly = true
-
   sources = [
     "android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthControllerTest.java",
     "android/java/src/org/chromium/chrome/browser/incognito/reauth/IncognitoReauthManagerTest.java",
@@ -128,7 +126,6 @@
     "//chrome/browser/tabmodel:java",
     "//chrome/browser/ui/android/layouts:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit:junit",
diff --git a/chrome/browser/loading_modal/android/BUILD.gn b/chrome/browser/loading_modal/android/BUILD.gn
index 49d4f70..ebdc669e 100644
--- a/chrome/browser/loading_modal/android/BUILD.gn
+++ b/chrome/browser/loading_modal/android/BUILD.gn
@@ -32,15 +32,12 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "junit/src/org/chromium/chrome/browser/loading_modal/LoadingModalDialogMediatorTest.java" ]
 
   deps = [
     ":java",
     "//base:base_java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn
index 937c0138..02c27a36 100644
--- a/chrome/browser/media/router/BUILD.gn
+++ b/chrome/browser/media/router/BUILD.gn
@@ -2,11 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//chrome/browser/media/router/features.gni")
 import("//extensions/buildflags/buildflags.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//testing/test.gni")
 
+declare_args() {
+  # Set to true to build code that supports the Open Screen Protocol.
+  # OSP is experimental and not yet feature-complete.
+  enable_openscreen_protocol = false
+}
+
 source_set("data_decoder_util") {
   deps = [
     "//base",
@@ -75,7 +80,7 @@
 
   if (!is_android) {
     deps += [
-      "discovery",
+      "discovery:discovery",
       "//build:chromeos_buildflags",
       "//chrome/browser:browser_process",
       "//chrome/browser/profiles:profile",
@@ -165,7 +170,7 @@
       deps += [ "//chrome/installer/util:with_no_strings" ]
     }
 
-    if (enable_openscreen) {
+    if (enable_openscreen_protocol) {
       sources += [
         "providers/openscreen/discovery/open_screen_listener.cc",
         "providers/openscreen/discovery/open_screen_listener.h",
@@ -195,7 +200,7 @@
   static_library("test_support") {
     testonly = true
     deps = [
-      "discovery",
+      "discovery:discovery",
       "//chrome/browser/media/router/discovery/access_code:discovery_resources_proto",
       "//chrome/test:test_support",
       "//components/cast_channel:cast_channel",
@@ -319,9 +324,8 @@
     ]
   }
 
-  if (enable_openscreen) {
+  if (enable_openscreen_protocol) {
     include_dirs = [ "//third_party/openscreen/src" ]
-
     sources += [
       "providers/openscreen/discovery/open_screen_listener_unittest.cc",
       "providers/openscreen/network_service_quic_packet_writer_unittest.cc",
@@ -329,7 +333,10 @@
   }
 }
 
-if (enable_openscreen) {
+# TODO(crbug.com/1290541): Fails to link on Fuchsia builds.
+# TODO(https://issuetracker.google.com/236160471): CDDL compiler doesn't build
+# on Windows.
+if (!is_fuchsia && !is_win) {
   test("openscreen_unittests") {
     deps = [
       "//base/test:run_all_unittests",
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc
index d04a3af..0ba5e53e 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc
@@ -168,105 +168,55 @@
   }
 
   std::vector<MediaRoute::Id> removed_routes;
-  std::set_difference(previous_routes_.begin(), previous_routes_.end(),
+  std::set_difference(old_routes_.begin(), old_routes_.end(),
                       new_routes.begin(), new_routes.end(),
                       std::inserter(removed_routes, removed_routes.end()));
-
-  std::vector<MediaRoute::Id> added_routes;
-  std::set_difference(new_routes.begin(), new_routes.end(),
-                      previous_routes_.begin(), previous_routes_.end(),
-                      std::inserter(added_routes, added_routes.end()));
-
-  previous_routes_ = new_routes;
-
-  if (!added_routes.empty()) {
-    // There should only be 1 element in the |added_routes| set.
-    DCHECK(added_routes.size() < 2) << "This value should only be 1, since "
-                                       "only one route can be added at a time.";
-    auto first = added_routes.begin();
-    added_route_id_ = *first;
-
-    base::PostTaskAndReplyWithResult(
-        access_code_sink_service_->GetCastMediaSinkServiceImpl()
-            ->task_runner()
-            .get(),
-        FROM_HERE,
-        base::BindOnce(
-            &CastMediaSinkServiceImpl::GetSinkById,
-            base::Unretained(
-                access_code_sink_service_->GetCastMediaSinkServiceImpl()),
-            MediaRoute::GetSinkIdFromMediaRouteId(added_route_id_)),
-        base::BindOnce(
-            &AccessCodeCastSinkService::HandleMediaRouteAddedByAccessCode,
-            access_code_sink_service_->GetWeakPtr()));
-  }
+  old_routes_ = new_routes;
 
   // No routes were removed.
   if (removed_routes.empty())
     return;
 
   // There should only be 1 element in the |removed_routes| set.
-  DCHECK(removed_routes.size() < 2)
-      << "This value should only be 1, since only one route can be removed at "
-         "a time.";
+  DCHECK(removed_routes.size() < 2);
   auto first = removed_routes.begin();
   removed_route_id_ = *first;
 
   base::PostTaskAndReplyWithResult(
-      access_code_sink_service_->GetCastMediaSinkServiceImpl()
-          ->task_runner()
+      access_code_sink_service_->cast_media_sink_service_impl_->task_runner()
           .get(),
       FROM_HERE,
       base::BindOnce(
           &CastMediaSinkServiceImpl::GetSinkById,
           base::Unretained(
-              access_code_sink_service_->GetCastMediaSinkServiceImpl()),
+              access_code_sink_service_->cast_media_sink_service_impl_),
           MediaRoute::GetSinkIdFromMediaRouteId(removed_route_id_)),
       base::BindOnce(
-          &AccessCodeCastSinkService::HandleMediaRouteRemovedByAccessCode,
+          &AccessCodeCastSinkService::HandleMediaRouteDiscoveredByAccessCode,
           access_code_sink_service_->GetWeakPtr()));
 }
 
-bool AccessCodeCastSinkService::IsSinkValidAccessCodeSink(
+void AccessCodeCastSinkService::HandleMediaRouteDiscoveredByAccessCode(
     const MediaSinkInternal* sink) {
   // The route Id did not correspond to a sink for some reason. Return to
   // avoid nullptr issues.
   if (!sink)
-    return false;
+    return;
+
   if (!sink->is_cast_sink()) {
-    return false;
+    return;
   }
+
   // Check to see if route was created by an access code sink.
   CastDiscoveryType type = sink->cast_data().discovery_type;
   if (type != CastDiscoveryType::kAccessCodeManualEntry &&
-      type != CastDiscoveryType::kAccessCodeRememberedDevice) {
-    return false;
-  }
-  return true;
-}
-
-void AccessCodeCastSinkService::HandleMediaRouteAddedByAccessCode(
-    const MediaSinkInternal* sink) {
-  if (!IsSinkValidAccessCodeSink(sink))
+        type != CastDiscoveryType::kAccessCodeRememberedDevice) {
     return;
-
-  // The timer object exists but Start() has not been called on it yet.
-  if (current_session_expiration_timers_.count(sink->id())) {
-    // Normally there is a delay in starting an expiration timer to ensure that
-    // we don't expire and remove the sink before the route has actually been
-    // made. Since we can confirm that the route was generated, we can start the
-    // expiration timer right now instead of waiting for the delay.
-    StartExpirationTimerWithDelay(sink, base::TimeDelta::FiniteMin());
   }
-}
 
-void AccessCodeCastSinkService::HandleMediaRouteRemovedByAccessCode(
-    const MediaSinkInternal* sink) {
-  if (!IsSinkValidAccessCodeSink(sink))
-    return;
   media_router_->GetLogger()->LogInfo(
-      mojom::LogCategory::kDiscovery, kLoggerComponent,
-      "An Access Code Cast route has ended.", sink->id(), "", "");
+    mojom::LogCategory::kDiscovery, kLoggerComponent,
+    "An Access Code Cast route has ended.", sink->id(), "", "");
 
   // There are two possible cases here. The common case is that a route for
   // the specified sink has been terminated by local or remote user
@@ -285,15 +235,15 @@
     std::move(it->second).Run(AddSinkResultCode::OK, sink->id());
     pending_callbacks_.erase(sink->id());
   } else {
-    // Need to pause just a little bit before attempting to remove the sink.
-    // Sometimes sinks terminate their routes and immediately start another
-    // (tab content transitions for example), so wait just a little while
-    // before checking to see if removing the route makes sense.
-    task_runner_->PostDelayedTask(
-        FROM_HERE,
-        base::BindOnce(&AccessCodeCastSinkService::OnAccessCodeRouteRemoved,
-                       weak_ptr_factory_.GetWeakPtr(), sink),
-        kExpirationDelay);
+      // Need to pause just a little bit before attempting to remove the sink.
+      // Sometimes sinks terminate their routes and immediately start another
+      // (tab content transitions for example), so wait just a little while
+      // before checking to see if removing the route makes sense.
+      task_runner_->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&AccessCodeCastSinkService::OnAccessCodeRouteRemoved,
+                         weak_ptr_factory_.GetWeakPtr(), sink),
+          kExpirationDelay);
   }
 }
 
@@ -306,19 +256,19 @@
   // another (preseentation). There was a pause before this method was called,
   // so check again to see if there's an active route for this sink. Only expire
   // the sink if a new route wasn't established during the pause.
-  auto route = GetActiveRoute(sink->id());
+  auto route_id = GetActiveRouteId(sink->id());
 
   // Only remove the sink if there is still no active routes for this sink.
   if (base::FeatureList::IsEnabled(features::kAccessCodeCastRememberDevices)) {
     // If a sink is pending expiration that means we can
     // remove it from the media router.
-    if (!route.has_value() && pending_expirations_.count(sink->id())) {
+    if (!route_id.has_value() && pending_expirations_.count(sink->id())) {
       RemoveSinkIdFromAllEntries(sink->id());
       RemoveMediaSinkFromRouter(sink);
       pending_expirations_.erase(sink->id());
     }
   } else {
-    if (!route.has_value()) {
+    if (!route_id.has_value()) {
       RemoveMediaSinkFromRouter(sink);
     }
   }
@@ -398,15 +348,15 @@
     // terminate the route before alerting the dialog to discovery success.
     // This is because any attempt to start a route on a sink that already has
     // one won't be successful.
-    auto route = GetActiveRoute(sink.id());
-    if (route.has_value()) {
+    auto route_id = GetActiveRouteId(sink.id());
+    if (route_id.has_value()) {
       media_router_->GetLogger()->LogInfo(mojom::LogCategory::kDiscovery,
                                           kLoggerComponent,
                                           "There was an existing route when "
                                           "discovery occurred, attempting to "
                                           "terminate it.",
                                           sink.id(), "", "");
-      media_router_->TerminateRoute(route.value().media_route_id());
+      media_router_->TerminateRoute(route_id.value());
       pending_callbacks_.emplace(sink.id(), std::move(add_sink_callback));
     } else {
       std::move(add_sink_callback).Run(AddSinkResultCode::OK, sink.id());
@@ -467,8 +417,8 @@
                      CreateCastSocketOpenParams(sink)));
 }
 
-absl::optional<const MediaRoute> AccessCodeCastSinkService::GetActiveRoute(
-    const MediaSink::Id& sink_id) {
+absl::optional<const MediaRoute::Id>
+AccessCodeCastSinkService::GetActiveRouteId(const MediaSink::Id& sink_id) {
   auto routes = media_router_->GetCurrentRoutes();
   auto route_it = std::find_if(routes.begin(), routes.end(),
                                [&sink_id](const MediaRoute& route) {
@@ -476,7 +426,7 @@
                                });
   if (route_it == routes.end())
     return absl::nullopt;
-  return *route_it;
+  return route_it->media_route_id();
 }
 
 cast_channel::CastSocketOpenParams
@@ -590,15 +540,6 @@
     return;
   }
 
-  // Make sure we include a delay in the case of instant expiration to ensure
-  // the sink is not removed before the route is created.
-  StartExpirationTimerWithDelay(
-      sink, AccessCodeCastSinkService::kExpirationTimerDelay);
-}
-
-void AccessCodeCastSinkService::StartExpirationTimerWithDelay(
-    const MediaSinkInternal* sink,
-    base::TimeDelta delay) {
   // Either retrieve collection or create it if it doesn't exist before an
   // operation can occur.
   auto existing_timer = current_session_expiration_timers_.find(sink->id());
@@ -606,13 +547,17 @@
     // We must first stop the timer before resetting it.
     existing_timer->second->Stop();
   }
-
   auto expiration_timer = std::make_unique<base::OneShotTimer>();
 
+  // Make sure we include a delay in the case of instant expiration to ensure
+  // the sink is not removed before the route is created.
   expiration_timer->Start(
-      FROM_HERE, CalculateDurationTillExpiration(sink->id()) + delay,
+      FROM_HERE,
+      CalculateDurationTillExpiration(sink->id()) +
+          AccessCodeCastSinkService::kExpirationTimerDelay,
       base::BindOnce(&AccessCodeCastSinkService::OnExpiration,
                      weak_ptr_factory_.GetWeakPtr(), *sink));
+
   current_session_expiration_timers_[sink->id()] = std::move(expiration_timer);
 }
 
@@ -717,10 +662,10 @@
           "references.",
       sink.id(), "", "");
 
-  auto route = GetActiveRoute(sink.id());
+  auto route_id = GetActiveRouteId(sink.id());
   // The given sink still has an active route, don't remove it yet and wait for
   // the route to end before we expire it.
-  if (route.has_value()) {
+  if (route_id.has_value()) {
     media_router_->GetLogger()->LogInfo(
         mojom::LogCategory::kDiscovery, kLoggerComponent,
         "The sink id: " + sink.id() +
@@ -747,10 +692,10 @@
   if (!sink) {
     return;
   }
-  DCHECK(!GetActiveRoute(sink->id()).has_value())
+  DCHECK(!GetActiveRouteId(sink->id()).has_value())
       << "This sink " + sink->id() +
              " still has an active route, we should not be removing it!";
-  if (GetActiveRoute(sink->id()).has_value())
+  if (GetActiveRouteId(sink->id()).has_value())
     return;
   media_router_->GetLogger()->LogInfo(
       mojom::LogCategory::kDiscovery, kLoggerComponent,
@@ -816,7 +761,7 @@
     // If there is an active route for this sink -- don't attempt to remove it.
     // In this case we let the Media Router handle removals from the media
     // router when a network is changed with an active route.
-    if (GetActiveRoute(sink_id).has_value()) {
+    if (GetActiveRouteId(sink_id).has_value()) {
       continue;
     }
 
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
index 19d4dac..13670b3 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
@@ -101,22 +101,18 @@
                              TestChangeNetworkWithRouteActive);
     FRIEND_TEST_ALL_PREFIXES(AccessCodeCastSinkServiceTest,
                              TestChangeNetworkWithRouteActiveExpiration);
-    FRIEND_TEST_ALL_PREFIXES(AccessCodeCastSinkServiceTest,
-                             TestExpirationTimerWithNoDelayStartedOnRouteAdded);
     // media_router::MediaRoutesObserver:
     void OnRoutesUpdated(const std::vector<MediaRoute>& routes) override;
 
     // Set of route ids that is updated whenever OnRoutesUpdated is called.
-    std::vector<MediaRoute::Id> previous_routes_;
+    std::vector<MediaRoute::Id> old_routes_;
 
     MediaRoute::Id removed_route_id_;
-    MediaRoute::Id added_route_id_;
 
     const raw_ptr<AccessCodeCastSinkService> access_code_sink_service_;
 
     base::WeakPtrFactory<AccessCodeMediaRoutesObserver> weak_ptr_factory_{this};
   };
-  // TODO(b/234892353): Remove friend class AccessCodeCastSinkServiceFactory
   friend class AccessCodeCastSinkServiceFactory;
   friend class AccessCodeCastSinkServiceTest;
   friend class AccessCodeCastHandlerTest;
@@ -173,8 +169,6 @@
                            TestChangeNetworkWithRouteActive);
   FRIEND_TEST_ALL_PREFIXES(AccessCodeCastSinkServiceTest,
                            TestChangeNetworkWithRouteActiveExpiration);
-  FRIEND_TEST_ALL_PREFIXES(AccessCodeCastSinkServiceTest,
-                           TestExpirationTimerWithNoDelayStartedOnRouteAdded);
 
   // Use |AccessCodeCastSinkServiceFactory::GetForProfile(..)| to get
   // an instance of this service.
@@ -196,16 +190,7 @@
                              MediaSink::Id sink_id,
                              bool channel_opened);
 
-  bool IsSinkValidAccessCodeSink(const MediaSinkInternal* sink);
-
-  // Handles removal from media router via expiration if a route with an access
-  // code cast sink has ended.
-  void HandleMediaRouteRemovedByAccessCode(const MediaSinkInternal* sink);
-
-  // Handles starting of expiration timers if a access code cast route has been
-  // added via access code casting.
-  void HandleMediaRouteAddedByAccessCode(const MediaSinkInternal* sink);
-
+  void HandleMediaRouteDiscoveredByAccessCode(const MediaSinkInternal* sink);
   void OnAccessCodeRouteRemoved(const MediaSinkInternal* sink);
   void OpenChannelIfNecessary(const MediaSinkInternal& sink,
                               AddSinkResultCallback add_sink_callback,
@@ -217,7 +202,8 @@
 
   // Returns a MediaRoute if the given |sink_id| corresponds to a route
   // currently active in the media router.
-  absl::optional<const MediaRoute> GetActiveRoute(const MediaSink::Id& sink_id);
+  absl::optional<const MediaRoute::Id> GetActiveRouteId(
+      const MediaSink::Id& sink_id);
 
   void InitAllStoredDevices();
   void InitExpirationTimers(const std::vector<MediaSinkInternal> cast_sinks);
@@ -264,12 +250,6 @@
   cast_channel::CastSocketOpenParams CreateCastSocketOpenParams(
       const MediaSinkInternal& sink);
 
-  // This function checks if a timer already exists for the given sink and
-  // resets it given the new delay. Otherwise it will simply start the timer
-  // with the given delay.
-  void StartExpirationTimerWithDelay(const MediaSinkInternal* sink,
-                                     base::TimeDelta delay);
-
   // KeyedService.
   void Shutdown() override;
 
@@ -278,11 +258,6 @@
     task_runner_ = task_runner;
   }
 
-  const raw_ptr<media_router::CastMediaSinkServiceImpl>
-  GetCastMediaSinkServiceImpl() {
-    return cast_media_sink_service_impl_;
-  }
-
   // Owns us via the KeyedService mechanism.
   const raw_ptr<Profile> profile_;
 
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
index 48dc397..8c01a798 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
@@ -270,7 +270,7 @@
 
   // Expect cast sink is NOT removed from the media router since it
   // is not an access code sink.
-  access_code_cast_sink_service_->HandleMediaRouteRemovedByAccessCode(
+  access_code_cast_sink_service_->HandleMediaRouteDiscoveredByAccessCode(
       &cast_sink1);
   EXPECT_CALL(*mock_cast_media_sink_service_impl(),
               DisconnectAndRemoveSink(cast_sink1))
@@ -288,7 +288,7 @@
       media_route_access.media_route_id());
   mock_time_task_runner()->FastForwardUntilNoTasksRemain();
 
-  access_code_cast_sink_service_->HandleMediaRouteRemovedByAccessCode(
+  access_code_cast_sink_service_->HandleMediaRouteDiscoveredByAccessCode(
       &access_code_sink2);
   // Expect that there is a pending attempt to examine the sink to see if it
   // should be expired.
@@ -347,7 +347,7 @@
 
   // Expect cast sink is NOT removed from the media router since it
   // is not an access code sink.
-  access_code_cast_sink_service_->HandleMediaRouteRemovedByAccessCode(
+  access_code_cast_sink_service_->HandleMediaRouteDiscoveredByAccessCode(
       &cast_sink1);
   EXPECT_CALL(*mock_cast_media_sink_service_impl(),
               DisconnectAndRemoveSink(cast_sink1))
@@ -365,7 +365,7 @@
       media_route_access.media_route_id());
   mock_time_task_runner()->FastForwardUntilNoTasksRemain();
 
-  access_code_cast_sink_service_->HandleMediaRouteRemovedByAccessCode(
+  access_code_cast_sink_service_->HandleMediaRouteDiscoveredByAccessCode(
       &access_code_sink2);
   // Expect that there is a pending attempt to examine the sink to see if it
   // should be expired.
@@ -425,7 +425,7 @@
       access_code_cast_sink_service_->media_routes_observer_->removed_route_id_,
       media_route_cast.media_route_id());
 
-  access_code_cast_sink_service_->HandleMediaRouteRemovedByAccessCode(
+  access_code_cast_sink_service_->HandleMediaRouteDiscoveredByAccessCode(
       &cast_sink1);
   mock_time_task_runner()->FastForwardUntilNoTasksRemain();
 }
@@ -932,55 +932,6 @@
   mock_time_task_runner()->FastForwardUntilNoTasksRemain();
 }
 
-TEST_F(AccessCodeCastSinkServiceTest,
-       TestExpirationTimerWithNoDelayStartedOnRouteAdded) {
-  // Test to see that an expiration timer will be started (and it will overwrite
-  // previous starts) IFF a route was successfully added for that sink.
-  // Otherwise the previous expiration timer with that given delay will hold.
-  MediaSinkInternal cast_sink1 = CreateCastSink(1);
-  cast_sink1.cast_data().discovery_type =
-      CastDiscoveryType::kAccessCodeManualEntry;
-  SetDeviceDurationPrefForTest(base::Seconds(1));
-  mock_cast_media_sink_service_impl()->AddSinkForTest(cast_sink1);
-
-  access_code_cast_sink_service_->StoreSinkAndSetExpirationTimer(
-      cast_sink1.id());
-  FastForwardUiAndIoTasks();
-  content::RunAllTasksUntilIdle();
-  FastForwardUiAndIoTasks();
-
-  // Expect the session timer is running.
-  EXPECT_TRUE(access_code_cast_sink_service_
-                  ->current_session_expiration_timers_[cast_sink1.id()]
-                  ->IsRunning());
-
-  // Because we have a delay on timers started before a route is added, going
-  // forward less than that delay should not expire the sink yet.
-  task_environment_.FastForwardBy(
-      AccessCodeCastSinkService::kExpirationTimerDelay - base::Seconds(5));
-
-  // Add a cast sink discovered by access code to the list of routes.
-  MediaRoute media_route_access = CreateRouteForTesting(cast_sink1);
-  std::vector<MediaRoute> route_list = {media_route_access};
-
-  // Expect that the added_route_id_ member variable includes the newly added
-  // route.
-  access_code_cast_sink_service_->media_routes_observer_->OnRoutesUpdated(
-      route_list);
-  EXPECT_FALSE(access_code_cast_sink_service_->media_routes_observer_
-                   ->added_route_id_.empty());
-  FastForwardUiAndIoTasks();
-  content::RunAllTasksUntilIdle();
-  FastForwardUiAndIoTasks();
-
-  // The timer should now be reset to include no delay since the route was
-  // successfully added. We now expire it.
-  task_environment_.FastForwardBy(base::Seconds(2));
-  EXPECT_FALSE(access_code_cast_sink_service_
-                   ->current_session_expiration_timers_[cast_sink1.id()]
-                   ->IsRunning());
-}
-
 TEST_F(AccessCodeCastSinkServiceTest, TestResetExpirationTimersNetworkChange) {
   // Test to check all expiration timers are restarted after network is changed.
   SetDeviceDurationPrefForTest(base::Seconds(10000));
diff --git a/chrome/browser/media/router/features.gni b/chrome/browser/media/router/features.gni
deleted file mode 100644
index 29a584e..0000000
--- a/chrome/browser/media/router/features.gni
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2019 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/chrome_build.gni")
-
-declare_args() {
-  # TODO(crbug.com/702997): Exclude openscreen in NaCl, since there is no packet
-  # support in that build configuration.  Once NaCl goes away, this check should
-  # be removed.
-  # NOTE: This option refers to the inclusion of code for the Open Screen
-  # Protocol, not the entire openscreen library.
-  enable_openscreen =
-      !is_nacl &&
-      (target_os == "linux" || target_os == "chromeos" || target_os == "mac")
-}
diff --git a/chrome/browser/notifications/BUILD.gn b/chrome/browser/notifications/BUILD.gn
index d5928adc..4845718b 100644
--- a/chrome/browser/notifications/BUILD.gn
+++ b/chrome/browser/notifications/BUILD.gn
@@ -100,8 +100,6 @@
   }
 
   robolectric_library("junit_tests") {
-    testonly = true
-
     sources = [
       "android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBaseTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/NotificationIntentInterceptorTest.java",
@@ -110,6 +108,7 @@
       "android/java/src/org/chromium/chrome/browser/notifications/PendingIntentProviderTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilderTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/ThrottlingNotificationSchedulerTest.java",
+      "android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsUpdaterTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/channels/ChromeChannelDefinitionsTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/permissions/NotificationPermissionChangeReceiverTest.java",
@@ -130,7 +129,6 @@
       "//components/embedder_support/android:junit_test_support",
       "//components/url_formatter/android:url_formatter_java",
       "//third_party/android_deps:espresso_java",
-      "//third_party/android_deps:robolectric_all_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/androidx:androidx_test_core_java",
       "//third_party/androidx:androidx_test_core_java",
@@ -151,7 +149,6 @@
       "android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilderTest.java",
       "android/java/src/org/chromium/chrome/browser/notifications/NotificationTestUtil.java",
       "android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactoryTest.java",
-      "android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java",
     ]
 
     deps = [
diff --git a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
index 8a443d2..9cf4f1b 100644
--- a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
+++ b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
@@ -10,31 +10,39 @@
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
 
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
 import android.content.Context;
 import android.os.Build;
-import android.support.test.InstrumentationRegistry;
 
 import androidx.annotation.RequiresApi;
-import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 
 import org.chromium.base.CollectionUtil;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.JniMocker;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.browser.notifications.NotificationSettingsBridge;
 import org.chromium.components.browser_ui.notifications.NotificationManagerProxy;
 import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl;
 import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer;
-import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
+import org.chromium.components.url_formatter.SchemeDisplay;
+import org.chromium.components.url_formatter.UrlFormatter;
+import org.chromium.components.url_formatter.UrlFormatterJni;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -42,25 +50,33 @@
 import java.util.List;
 
 /**
- * Instrumentation tests for ChannelsInitializer, using ChromeChannelDefinitions.
- *
- * These are Android instrumentation tests so that resource strings can be accessed, and so that
- * we can test against the real NotificationManager implementation.
+ * Robolectric tests for ChannelsInitializer, using ChromeChannelDefinitions.
  */
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(BaseRobolectricTestRunner.class)
 public class ChannelsInitializerTest {
     private ChannelsInitializer mChannelsInitializer;
     private NotificationManagerProxy mNotificationManagerProxy;
     private Context mContext;
+    @Rule
+    public JniMocker mJniMocker = new JniMocker();
+    @Mock
+    private UrlFormatter.Natives mUrlFormatterJniMock;
 
     @Before
     @RequiresApi(Build.VERSION_CODES.O)
     public void setUp() {
-        // Not initializing the browser process is safe because
-        // UrlFormatter.formatUrlForSecurityDisplay() is stand-alone.
-        NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess();
+        MockitoAnnotations.initMocks(this);
+        mJniMocker.mock(UrlFormatterJni.TEST_HOOKS, mUrlFormatterJniMock);
+        when(mUrlFormatterJniMock.formatStringUrlForSecurityDisplay(
+                     anyString(), eq(SchemeDisplay.OMIT_HTTP_AND_HTTPS)))
+                .then(inv -> {
+                    String url = inv.getArgument(0);
+                    return url != null && url.contains("://")
+                            ? url.substring(url.indexOf("://") + 3)
+                            : url;
+                });
 
-        mContext = InstrumentationRegistry.getTargetContext();
+        mContext = RuntimeEnvironment.getApplication();
         mNotificationManagerProxy = new NotificationManagerProxyImpl(mContext);
         mChannelsInitializer = new ChannelsInitializer(mNotificationManagerProxy,
                 ChromeChannelDefinitions.getInstance(), mContext.getResources());
@@ -80,7 +96,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -99,7 +114,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -117,7 +131,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -129,7 +142,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -143,12 +155,11 @@
         channel.setGroup(ChromeChannelDefinitions.ChannelGroupId.GENERAL);
         mNotificationManagerProxy.createNotificationChannelGroup(group);
         mNotificationManagerProxy.createNotificationChannel(channel);
-        mContext = InstrumentationRegistry.getTargetContext();
+        mContext = RuntimeEnvironment.getApplication();
         mChannelsInitializer.updateLocale(mContext.getResources());
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -165,7 +176,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -183,7 +193,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -201,7 +210,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -219,7 +227,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -238,7 +245,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -261,7 +267,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -280,7 +285,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -300,7 +304,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -311,7 +314,7 @@
     }
 
     @Test
-    @SmallTest
+
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -327,7 +330,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -345,7 +347,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -363,7 +364,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -381,7 +381,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
@@ -399,7 +398,6 @@
     }
 
     @Test
-    @SmallTest
     @MinAndroidSdkLevel(Build.VERSION_CODES.O)
     @RequiresApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
diff --git a/chrome/browser/optimization_guide/android/BUILD.gn b/chrome/browser/optimization_guide/android/BUILD.gn
index 91c894b..7800570 100644
--- a/chrome/browser/optimization_guide/android/BUILD.gn
+++ b/chrome/browser/optimization_guide/android/BUILD.gn
@@ -67,19 +67,41 @@
   ]
 }
 
-android_library("javatests") {
+android_library("unit_device_javatests") {
   testonly = true
 
   sources = [
-    "javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactoryUnitTest.java",
-    "javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java",
-    "javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java",
+    "java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java",
+    "java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java",
   ]
 
   deps = [
     ":java",
     "//base:base_java",
     "//base:base_java_test_support",
+    "//chrome/browser/flags:java",
+    "//chrome/browser/preferences:java",
+    "//chrome/browser/profiles/android:java",
+    "//components/optimization_guide/proto:optimization_guide_proto_java",
+    "//content/public/android:content_full_java",
+    "//content/public/test/android:content_java_test_support",
+    "//third_party/android_deps:protobuf_lite_runtime_java",
+    "//third_party/androidx:androidx_test_runner_java",
+    "//third_party/junit:junit",
+    "//third_party/mockito:mockito_java",
+    "//url:gurl_java",
+  ]
+}
+
+android_library("javatests") {
+  testonly = true
+
+  sources = [ "javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeFactoryUnitTest.java" ]
+
+  deps = [
+    ":java",
+    "//base:base_java",
+    "//base:base_java_test_support",
     "//chrome/android:chrome_test_util_java",
     "//chrome/browser/flags:java",
     "//chrome/browser/preferences:java",
diff --git a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
similarity index 100%
rename from chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
rename to chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
diff --git a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java
similarity index 100%
rename from chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java
rename to chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java
diff --git a/chrome/browser/page_annotations/test/android/BUILD.gn b/chrome/browser/page_annotations/test/android/BUILD.gn
index 8c9f0a4..0d51a3bc 100644
--- a/chrome/browser/page_annotations/test/android/BUILD.gn
+++ b/chrome/browser/page_annotations/test/android/BUILD.gn
@@ -6,8 +6,6 @@
 import("//build/config/android/rules.gni")
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/page_annotations/BuyableProductPageAnnotationUnitTest.java",
     "java/src/org/chromium/chrome/browser/page_annotations/PageAnnotationUtilsUnitTest.java",
@@ -25,7 +23,6 @@
     "//chrome/browser/page_annotations/android:java",
     "//chrome/browser/profiles/android:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/chrome/browser/partnerbookmarks/BUILD.gn b/chrome/browser/partnerbookmarks/BUILD.gn
index 65c1cde..36240ca 100644
--- a/chrome/browser/partnerbookmarks/BUILD.gn
+++ b/chrome/browser/partnerbookmarks/BUILD.gn
@@ -50,8 +50,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "junit/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksFaviconThrottleTest.java",
     "junit/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReaderTest.java",
@@ -62,7 +60,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//chrome/browser/partnercustomizations:java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit:junit",
diff --git a/chrome/browser/password_edit_dialog/android/BUILD.gn b/chrome/browser/password_edit_dialog/android/BUILD.gn
index 8cce0c71..3f34dbcf 100644
--- a/chrome/browser/password_edit_dialog/android/BUILD.gn
+++ b/chrome/browser/password_edit_dialog/android/BUILD.gn
@@ -69,7 +69,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/password_edit_dialog/PasswordEditDialogTest.java" ]
 
   deps = [
@@ -79,7 +78,6 @@
     "//base:base_junit_test_support",
     "//chrome/browser/flags:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/password_entry_edit/android/internal/BUILD.gn b/chrome/browser/password_entry_edit/android/internal/BUILD.gn
index fe7d024..2e37ab1 100644
--- a/chrome/browser/password_entry_edit/android/internal/BUILD.gn
+++ b/chrome/browser/password_entry_edit/android/internal/BUILD.gn
@@ -39,7 +39,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditControllerTest.java" ]
 
   deps = [
@@ -48,7 +47,6 @@
     "//base:base_junit_test_support",
     "//chrome/browser/password_entry_edit/android:java",
     "//chrome/browser/password_manager/android:java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/junit",
diff --git a/chrome/browser/payments/android/BUILD.gn b/chrome/browser/payments/android/BUILD.gn
index 2f17496..93dd80d 100644
--- a/chrome/browser/payments/android/BUILD.gn
+++ b/chrome/browser/payments/android/BUILD.gn
@@ -14,7 +14,6 @@
 
 # TODO(crbug.com/1164979): remove the dependency on chrome_java.
 robolectric_library("junit_test_support") {
-  testonly = true
   deps = [
     "//chrome/android:chrome_java",
     "//chrome/browser/android/lifecycle:java",
@@ -27,7 +26,6 @@
     "//content/public/android:content_java",
     "//mojo/public/java:bindings_java",
     "//mojo/public/java:system_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
     "//third_party/mockito:mockito_java",
@@ -45,7 +43,6 @@
 
 # TODO(crbug.com/1164979): remove the dependency on chrome_java.
 robolectric_library("junit") {
-  testonly = true
   deps = [
     ":junit_test_support",
     "//base:base_java_test_support",
@@ -61,7 +58,6 @@
     "//mojo/public/java:bindings_java",
     "//mojo/public/java:system_java",
     "//services/service_manager/public/java:service_manager_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/policy/android/BUILD.gn b/chrome/browser/policy/android/BUILD.gn
index 31836cab..4af5c33 100644
--- a/chrome/browser/policy/android/BUILD.gn
+++ b/chrome/browser/policy/android/BUILD.gn
@@ -68,8 +68,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/policy/CloudManagementAndroidConnectionTest.java",
     "java/src/org/chromium/chrome/browser/policy/CloudManagementSharedPreferencesTest.java",
@@ -81,7 +79,6 @@
     ":util_java",
     "//base:base_junit_test_support",
     "//chrome/browser/preferences:java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
   ]
diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn
index 5657e49..683b1b6 100644
--- a/chrome/browser/preferences/BUILD.gn
+++ b/chrome/browser/preferences/BUILD.gn
@@ -54,7 +54,6 @@
 }
 
 robolectric_library("preferences_junit_tests") {
-  testonly = true
   sources = [
     "android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeyCheckerTest.java",
     "android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeysTest.java",
diff --git a/chrome/browser/resources/app_service_internals/app_service_internals.ts b/chrome/browser/resources/app_service_internals/app_service_internals.ts
index 540e2fc..bc5c419 100644
--- a/chrome/browser/resources/app_service_internals/app_service_internals.ts
+++ b/chrome/browser/resources/app_service_internals/app_service_internals.ts
@@ -51,7 +51,7 @@
    * Manually responds to URL hash changes, since the regular browser handling
    * doesn't work in the Shadow DOM.
    */
-  onHashChanged_() {
+  private onHashChanged_() {
     if (!location.hash || !this.shadowRoot) {
       window.scrollTo(0, 0);
       return;
@@ -65,7 +65,7 @@
     selected.scrollIntoView();
   }
 
-  save_() {
+  private save_() {
     const fileParts = [];
     fileParts.push('App List\n');
     fileParts.push('========\n\n');
diff --git a/chrome/browser/resources/bookmarks/app.ts b/chrome/browser/resources/bookmarks/app.ts
index 82b29645..aa6a0f1 100644
--- a/chrome/browser/resources/bookmarks/app.ts
+++ b/chrome/browser/resources/bookmarks/app.ts
@@ -233,6 +233,7 @@
   }
 
   /** Overridden from IronScrollTargetBehavior */
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
   override _scrollHandler() {
     this.toolbarShadow_ = this.scrollTarget!.scrollTop !== 0;
   }
diff --git a/chrome/browser/resources/bookmarks/command_manager.ts b/chrome/browser/resources/bookmarks/command_manager.ts
index d2815847..7cf16bb 100644
--- a/chrome/browser/resources/bookmarks/command_manager.ts
+++ b/chrome/browser/resources/bookmarks/command_manager.ts
@@ -243,7 +243,7 @@
     }
   }
 
-  isCommandVisible_(command: Command, itemIds: Set<string>): boolean {
+  private isCommandVisible_(command: Command, itemIds: Set<string>): boolean {
     switch (command) {
       case Command.EDIT:
         return itemIds.size === 1 && this.globalCanEdit_;
diff --git a/chrome/browser/resources/browser_switch/internals/app.ts b/chrome/browser/resources/browser_switch/internals/app.ts
index ba7fef6b..58cc6c7 100644
--- a/chrome/browser/resources/browser_switch/internals/app.ts
+++ b/chrome/browser/resources/browser_switch/internals/app.ts
@@ -180,7 +180,7 @@
     return [opensIn, reason];
   }
 
-  checkUrl_(url: string) {
+  private checkUrl_(url: string) {
     if (!url) {
       this.urlCheckerOutput_ = [];
       return;
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util.js
index 8a75968..d33b4008 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util.js
@@ -158,6 +158,35 @@
     return 0;
   }
 
+
+  /**
+   * @param {string} value
+   * @param {number} caretIndex
+   * @param {string} text
+   * @return {string}
+   */
+  static adjustCommitText(value, caretIndex, commitText) {
+    // There is currently a bug in SODA (b/213934503) where final speech results
+    // do not start with a space. This results in a Dictation bug
+    // (crbug.com/1294050), where final speech results are not separated by a
+    // space when committed to a text field. This is a temporary workaround
+    // until the blocking SODA bug can be fixed. Note, a similar strategy
+    // already exists in Dictation::OnSpeechResult().
+    if (!value || EditingUtil.BEGINS_WITH_WHITESPACE_REGEX_.test(commitText) ||
+        EditingUtil.BEGINS_WITH_PUNCTUATION_REGEX_.test(commitText)) {
+      return commitText;
+    }
+
+    // Prepend a space to `commitText`, unless there is whitespace directly left
+    // of the cursor.
+    const leftOfCaret = value[caretIndex - 1];
+    if (EditingUtil.BEGINS_WITH_WHITESPACE_REGEX_.test(leftOfCaret)) {
+      return commitText;
+    }
+
+    return ' ' + commitText;
+  }
+
   /**
    * Returns a RegExp that matches on the right-most occurrence of a phrase.
    * The returned RegExp is case insensitive and requires that `phrase` is
@@ -209,3 +238,10 @@
  */
 EditingUtil.PUNCTUATION_REGEX_ =
     /[-$#"()*;:<>\n\\\/\{\}\[\]+='~`!@_.,?%\u2022\u25e6\u25a0]/g;
+
+/**
+ * @private {!RegExp}
+ * @const
+ */
+EditingUtil.BEGINS_WITH_PUNCTUATION_REGEX_ =
+    /^[-$#"()*;:<>\n\\\/\{\}\[\]+='~`!@_.,?%\u2022\u25e6\u25a0]/;
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util_test.js
index c976830b..6d0ba57 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/editing_util_test.js
@@ -309,3 +309,37 @@
   caretIndex = 0;
   assertEquals(0, f());
 });
+
+SYNC_TEST_F('DictationEditingUtilTest', 'AdjustCommitText', function() {
+  let value;
+  let caretIndex;
+  let commitText;
+  const f = () => EditingUtil.adjustCommitText(value, caretIndex, commitText);
+
+  // Add an extra space.
+  value = 'This is a test.';
+  caretIndex = value.length;
+  commitText = 'More text';
+  assertEquals(' More text', f());
+
+  value = 'This is a test';
+  caretIndex = value.length;
+  commitText = 'folks!';
+  assertEquals(' folks!', f());
+
+  // Don't add a space.
+  value = 'This is a test. ';
+  caretIndex = value.length;
+  commitText = 'More text';
+  assertEquals('More text', f());
+
+  value = 'This is a test.';
+  caretIndex = value.length;
+  commitText = ' More text';
+  assertEquals(' More text', f());
+
+  value = 'This is a test';
+  caretIndex = value.length;
+  commitText = '!';
+  assertEquals('!', f());
+});
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
index 6c130e29..fa4f762 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
@@ -100,7 +100,14 @@
       return;
     }
 
-    text = this.adjustCommitText_(text);
+    const editableNode = this.focusHandler_.getEditableNode();
+    if (editableNode && editableNode.textSelStart === editableNode.textSelEnd) {
+      // Adjust the commit text to preserve spacing.
+      const value = editableNode.value;
+      const caretIndex = editableNode.textSelStart;
+      text = EditingUtil.adjustCommitText(value, caretIndex, text);
+    }
+
     chrome.input.ime.commitText({contextID: this.activeImeContextId_, text});
   }
 
@@ -135,36 +142,6 @@
   }
 
   /**
-   * @param {string} text
-   * @return {string}
-   */
-  adjustCommitText_(text) {
-    // There is currently a bug in SODA (b/213934503) where final speech results
-    // do not start with a space. This results in a Dictation bug
-    // (crbug.com/1294050), where final speech results are not separated by a
-    // space when committed to a text field. This is a temporary workaround
-    // until the blocking SODA bug can be fixed. Note, a similar strategy
-    // already exists in Dictation::OnSpeechResult().
-    const editableNode = this.focusHandler_.getEditableNode();
-    if (!editableNode ||
-        InputController.BEGINS_WITH_WHITESPACE_REGEX_.test(text)) {
-      return text;
-    }
-
-    const value = editableNode.value;
-    const selStart = editableNode.textSelStart;
-    const selEnd = editableNode.textSelEnd;
-    // Prepend a space to `text` if there is text directly left of the cursor.
-    if (!selStart || selStart !== selEnd || !value ||
-        InputController.BEGINS_WITH_WHITESPACE_REGEX_.test(
-            value[selStart - 1])) {
-      return text;
-    }
-
-    return ' ' + text;
-  }
-
-  /**
    * Deletes the sentence to the left of the text caret. If the caret is in the
    * middle of a sentence, it will delete a portion of the sentence it
    * intersects.
@@ -317,9 +294,3 @@
  * @const
  */
 InputController.NO_ACTIVE_IME_CONTEXT_ID_ = -1;
-
-/**
- * @private {!RegExp}
- * @const
- */
-InputController.BEGINS_WITH_WHITESPACE_REGEX_ = /^\s/;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js
index f9662cc..e74c8559 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_test.js
@@ -133,8 +133,8 @@
 });
 
 
-// TODO(https://crbug.com/1333375): Flaky on MSAN builders.
-GEN('#if defined(MEMORY_SANITIZER)');
+// TODO(https://crbug.com/1333375): Flaky on MSAN and ASAN builders.
+GEN('#if defined(MEMORY_SANITIZER) || defined(ADDRESS_SANITIZER)');
 GEN('#define MAYBE_SearchMenu DISABLED_SearchMenu');
 GEN('#else');
 GEN('#define MAYBE_SearchMenu SearchMenu');
diff --git a/chrome/browser/resources/chromeos/arc_input_overlay/onboarding_illustration_dark.png b/chrome/browser/resources/chromeos/arc_input_overlay/onboarding_illustration_dark.png
new file mode 100644
index 0000000..9d4ae92
--- /dev/null
+++ b/chrome/browser/resources/chromeos/arc_input_overlay/onboarding_illustration_dark.png
Binary files differ
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 9fc0cfb2..077c2c1f4 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -80,6 +80,7 @@
         <include name="IDR_ARC_SUPPORT_RECOMMEND_APP_OLD_LIST_VIEW_HTML" file="chromeos/arc_support/recommend_app_old_list_view.html" type="chrome_html" flattenhtml="true" />
         <include name="IDR_ARC_SUPPORT_RECOMMEND_APP_LIST_VIEW_HTML" file="chromeos/arc_support/recommend_app_list_view.html" type="chrome_html" flattenhtml="true" />
         <include name="IDS_ARC_INPUT_OVERLAY_ONBOARDING_ILLUSTRATION" file="chromeos/arc_input_overlay/onboarding_illustration.png" type="BINDATA" />
+        <include name="IDS_ARC_INPUT_OVERLAY_ONBOARDING_ILLUSTRATION_DARK" file="chromeos/arc_input_overlay/onboarding_illustration_dark.png" type="BINDATA" />
       </if>
       <include name="IDR_CRYPTOTOKEN_UTIL_JS" file="cryptotoken/util.js" type="BINDATA" />
       <include name="IDR_CRYPTOTOKEN_B64_JS" file="cryptotoken/b64.js" type="BINDATA" />
diff --git a/chrome/browser/resources/extensions/service.ts b/chrome/browser/resources/extensions/service.ts
index 64dcfff..5132a93 100644
--- a/chrome/browser/resources/extensions/service.ts
+++ b/chrome/browser/resources/extensions/service.ts
@@ -110,7 +110,7 @@
    * Opens a file browser dialog for the user to select a file (or directory).
    * @return The promise to be resolved with the selected path.
    */
-  chooseFilePath_(
+  private chooseFilePath_(
       selectType: chrome.developerPrivate.SelectType,
       fileType: chrome.developerPrivate.FileType): Promise<string> {
     return new Promise(function(resolve, reject) {
diff --git a/chrome/browser/resources/history/app.ts b/chrome/browser/resources/history/app.ts
index c52b96ec..1d48467b 100644
--- a/chrome/browser/resources/history/app.ts
+++ b/chrome/browser/resources/history/app.ts
@@ -334,6 +334,7 @@
   }
 
   /** Overridden from IronScrollTargetBehavior */
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
   override _scrollHandler() {
     if (this.scrollTarget) {
       // When the tabs are visible, show the toolbar shadow for the synced
diff --git a/chrome/browser/resources/history/history_item.ts b/chrome/browser/resources/history/history_item.ts
index a8d9740..9d1a655 100644
--- a/chrome/browser/resources/history/history_item.ts
+++ b/chrome/browser/resources/history/history_item.ts
@@ -297,7 +297,7 @@
     }
   }
 
-  onLinkRightClick_() {
+  private onLinkRightClick_() {
     BrowserServiceImpl.getInstance().recordAction('EntryLinkRightClick');
   }
 
diff --git a/chrome/browser/resources/history/synced_device_manager.ts b/chrome/browser/resources/history/synced_device_manager.ts
index ccb92c7b..af0b115e 100644
--- a/chrome/browser/resources/history/synced_device_manager.ts
+++ b/chrome/browser/resources/history/synced_device_manager.ts
@@ -334,7 +334,7 @@
    * tabs page. Sign in promo gets displayed when user is signed out, and
    * different messages are shown when there are no synced tabs.
    */
-  signInStateChanged_(_current: boolean, previous?: boolean) {
+  private signInStateChanged_(_current: boolean, previous?: boolean) {
     if (previous === undefined) {
       return;
     }
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.ts b/chrome/browser/resources/new_tab_page/modules/modules.ts
index d6443ab9..21b78ef 100644
--- a/chrome/browser/resources/new_tab_page/modules/modules.ts
+++ b/chrome/browser/resources/new_tab_page/modules/modules.ts
@@ -338,8 +338,7 @@
     return this.modulesLoaded_ && this.modulesVisibilityDetermined_;
   }
 
-  /** @private */
-  onModulesLoadedAndVisibilityDeterminedChange_() {
+  private onModulesLoadedAndVisibilityDeterminedChange_() {
     if (this.modulesLoadedAndVisibilityDetermined_) {
       ModuleRegistry.getInstance().getDescriptors().forEach(({id}) => {
         chrome.metricsPrivate.recordBoolean(
@@ -412,8 +411,7 @@
         this.disabledModules_.ids.includes(id);
   }
 
-  /** @private */
-  onUndoRemoveModuleButtonClick_() {
+  private onUndoRemoveModuleButtonClick_() {
     if (!this.removedModuleData_) {
       return;
     }
@@ -433,9 +431,8 @@
 
   /**
    * Hides and reveals modules depending on removed status.
-   * @private
    */
-  onRemovedModulesChange_() {
+  private onRemovedModulesChange_() {
     this.shadowRoot!.querySelectorAll('ntp-module-wrapper')
         .forEach(moduleWrapper => {
           moduleWrapper.parentElement!.hidden =
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar.ts b/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
index c26950e..cc25d70b 100644
--- a/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
+++ b/chrome/browser/resources/pdf/elements/viewer-toolbar.ts
@@ -217,19 +217,19 @@
     this.dispatchEvent(new CustomEvent('properties-click'));
   }
 
-  getSinglePageAriaChecked_(checked: boolean): string {
+  private getSinglePageAriaChecked_(checked: boolean): string {
     return checked ? 'false' : 'true';
   }
 
-  getTwoPageViewAriaChecked_(checked: boolean): string {
+  private getTwoPageViewAriaChecked_(checked: boolean): string {
     return checked ? 'true' : 'false';
   }
 
-  getShowAnnotationsAriaChecked_(checked: boolean): string {
+  private getShowAnnotationsAriaChecked_(checked: boolean): string {
     return checked ? 'true' : 'false';
   }
 
-  getAriaExpanded_(): string {
+  private getAriaExpanded_(): string {
     return this.sidenavCollapsed ? 'false' : 'true';
   }
 
diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts
index 904704e..a22dd8209 100644
--- a/chrome/browser/resources/pdf/pdf_viewer.ts
+++ b/chrome/browser/resources/pdf/pdf_viewer.ts
@@ -484,7 +484,7 @@
   }
 
   /** Exits annotation mode if active. */
-  async exitAnnotationMode_(): Promise<void> {
+  private async exitAnnotationMode_(): Promise<void> {
     if (!this.$.toolbar.annotationMode) {
       return;
     }
diff --git a/chrome/browser/resources/pdf/viewport.ts b/chrome/browser/resources/pdf/viewport.ts
index 77c2878..85d6a9f 100644
--- a/chrome/browser/resources/pdf/viewport.ts
+++ b/chrome/browser/resources/pdf/viewport.ts
@@ -1564,7 +1564,7 @@
   /**
    * Dispatches a "scroll" event.
    */
-  dispatchScroll_() {
+  private dispatchScroll_() {
     this.target_ && this.target_.dispatchEvent(new Event('scroll'));
   }
 
diff --git a/chrome/browser/resources/print_preview/ui/sidebar.ts b/chrome/browser/resources/print_preview/ui/sidebar.ts
index f9c156a..51d06642 100644
--- a/chrome/browser/resources/print_preview/ui/sidebar.ts
+++ b/chrome/browser/resources/print_preview/ui/sidebar.ts
@@ -193,7 +193,7 @@
   /**
    * @return Whether to show the "More settings" link.
    */
-  computeShouldShowMoreSettings_(): boolean {
+  private computeShouldShowMoreSettings_(): boolean {
     // Destination settings is always available. See if the total number of
     // available sections exceeds the maximum number to show.
     return [
diff --git a/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.ts b/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.ts
index 8d230c6..d9f78ce2 100644
--- a/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.ts
+++ b/chrome/browser/resources/settings/autofill_page/multi_store_password_ui_entry.ts
@@ -74,7 +74,7 @@
   /**
    * Extract all the information except for the id and fromPasswordStore.
    */
-  static getContents_(entry: chrome.passwordsPrivate.PasswordUiEntry):
+  private static getContents_(entry: chrome.passwordsPrivate.PasswordUiEntry):
       MultiStorePasswordUiEntryContents {
     return {
       urls: entry.urls,
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.html
index e7e4e93..3073e5db 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.html
@@ -72,6 +72,17 @@
   </template>
 </div>
 <template is="dom-if"
+    if="[[isFastPairSavedDevicesRowVisible_(isFastPairSupportedByDevice_)]]">
+  <cr-link-row
+      class="hr two-line"
+      id="savedDevicesRowLink"
+      label="$i18n{savedDevicesLabel}"
+      sub-label="[[savedDevicesSublabel_]]">
+  </cr-link-row>
+</template>
+<div class="device-lists-separator"></div>
+
+<template is="dom-if"
     if="[[isFastPairToggleVisible_(isFastPairSupportedByDevice_)]]">
   <settings-fast-pair-toggle prefs="{{prefs}}"
       id="enableFastPairToggle"
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js
index 3365136..cc8dbc4 100644
--- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_devices_subpage.js
@@ -110,6 +110,16 @@
       },
 
       /**
+       * @private
+       */
+      savedDevicesSublabel_: {
+        type: String,
+        value() {
+          return loadTimeData.getString('sublableWithEmail');
+        },
+      },
+
+      /**
        * @private {!Array<!PairedBluetoothDeviceProperties>}
        */
       unconnectedDevices_: {
@@ -299,6 +309,15 @@
     return this.isFastPairSupportedByDevice_ &&
         loadTimeData.getBoolean('enableFastPairFlag');
   }
+
+  /**
+   * @return {boolean}
+   * @private
+   */
+  isFastPairSavedDevicesRowVisible_() {
+    return this.isFastPairSupportedByDevice_ &&
+        loadTimeData.getBoolean('enableSavedDevicesFlag');
+  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/settings/controls/settings_idle_load.ts b/chrome/browser/resources/settings/controls/settings_idle_load.ts
index cbb782e..416c2224 100644
--- a/chrome/browser/resources/settings/controls/settings_idle_load.ts
+++ b/chrome/browser/resources/settings/controls/settings_idle_load.ts
@@ -94,6 +94,7 @@
     return this.loading_;
   }
 
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
   private _forwardHostPropV2(prop: string, value: any) {
     if (this.instance_) {
       this.instance_.forwardHostProp(prop, value);
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.ts b/chrome/browser/resources/settings/languages_page/languages_page.ts
index e171549..20b098fd 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.ts
+++ b/chrome/browser/resources/settings/languages_page/languages_page.ts
@@ -164,7 +164,7 @@
    * of spellcheck languages, based on whether or not the language is enabled.
    * @param isEnabled Whether the language is enabled or not.
    */
-  getIndicatorPrefForManagedSpellcheckLanguage_(isEnabled: boolean):
+  private getIndicatorPrefForManagedSpellcheckLanguage_(isEnabled: boolean):
       chrome.settingsPrivate.PrefObject {
     return isEnabled ? this.get('spellcheck.forced_dictionaries', this.prefs) :
                        this.get('spellcheck.blocked_dictionaries', this.prefs);
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.ts b/chrome/browser/resources/settings/languages_page/languages_subpage.ts
index 0534e9e..ce99c9f 100644
--- a/chrome/browser/resources/settings/languages_page/languages_subpage.ts
+++ b/chrome/browser/resources/settings/languages_page/languages_subpage.ts
@@ -329,7 +329,8 @@
    * @return 'target' if |languageCode| matches the target language,
    *     'non-target' otherwise.
    */
-  isTranslationTarget_(languageCode: string, translateTarget: string): string {
+  private isTranslationTarget_(languageCode: string, translateTarget: string):
+      string {
     if (this.languageHelper.convertLanguageCodeForTranslate(languageCode) ===
         translateTarget) {
       return 'target';
@@ -489,7 +490,7 @@
    * Returns "complex" if the menu includes checkboxes, which should change
    * the spacing of items and show a separator in the menu.
    */
-  getMenuClass_(translateEnabled: boolean): string {
+  private getMenuClass_(translateEnabled: boolean): string {
     if (translateEnabled || isWindows) {
       return 'complex';
     }
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.ts b/chrome/browser/resources/settings/people_page/sync_account_control.ts
index 09f83a40..fe7b37e 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.ts
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.ts
@@ -170,7 +170,7 @@
   /**
    * Records Signin_Impression_FromSettings user action.
    */
-  recordImpressionUserActions_() {
+  private recordImpressionUserActions_() {
     assert(!this.syncStatus.signedIn);
 
     chrome.metricsPrivate.recordUserAction('Signin_Impression_FromSettings');
diff --git a/chrome/browser/resources/settings/people_page/sync_controls.ts b/chrome/browser/resources/settings/people_page/sync_controls.ts
index 177e113..4e98ea2 100644
--- a/chrome/browser/resources/settings/people_page/sync_controls.ts
+++ b/chrome/browser/resources/settings/people_page/sync_controls.ts
@@ -201,7 +201,7 @@
     this.onSingleSyncDataTypeChanged_();
   }
 
-  shouldPaymentsCheckboxBeDisabled_(
+  private shouldPaymentsCheckboxBeDisabled_(
       syncAllDataTypes: boolean, autofillSynced: boolean): boolean {
     return syncAllDataTypes || !autofillSynced;
   }
diff --git a/chrome/browser/resources/settings/privacy_page/secure_dns.ts b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
index 01e2d76..87a3027d 100644
--- a/chrome/browser/resources/settings/privacy_page/secure_dns.ts
+++ b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
@@ -200,7 +200,7 @@
    * selection (and the underlying radio button if the toggle has just been
    * enabled).
    */
-  onToggleChanged_() {
+  private onToggleChanged_() {
     this.showRadioGroup_ = this.secureDnsToggle_.value;
     if (this.secureDnsRadio_ === SecureDnsMode.SECURE &&
         !this.$.secureResolverSelect.value) {
@@ -275,7 +275,7 @@
    * resolver and displays the corresponding privacy policy. Focuses the custom
    * text field if the custom option has been selected.
    */
-  onDropdownSelectionChanged_() {
+  private onDropdownSelectionChanged_() {
     // If we're already in secure mode, update the prefs.
     if (this.secureDnsRadio_ === SecureDnsMode.SECURE) {
       this.updateDnsPrefs_(SecureDnsMode.SECURE);
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 4790d893..e6d251c9 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
@@ -117,7 +117,7 @@
   private lastFocused_: HTMLElement;
   private listBlurred_: boolean;
 
-  computeVisibleEngines_(engines: Array<SearchEngine>) {
+  private computeVisibleEngines_(engines: Array<SearchEngine>) {
     if (!engines || !engines.length) {
       return;
     }
@@ -125,7 +125,7 @@
     return engines.slice(0, this.visibleEnginesSize);
   }
 
-  computeCollapsedEngines_(engines: Array<SearchEngine>) {
+  private computeCollapsedEngines_(engines: Array<SearchEngine>) {
     if (!engines || !engines.length) {
       return;
     }
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.ts b/chrome/browser/resources/settings/site_settings/all_sites.ts
index e47b15ba..c2f1ee2 100644
--- a/chrome/browser/resources/settings/site_settings/all_sites.ts
+++ b/chrome/browser/resources/settings/site_settings/all_sites.ts
@@ -455,12 +455,12 @@
     this.$.menu.get().showAt(target);
   }
 
-  onRemoveSite_(e: RemoveSiteEvent) {
+  private onRemoveSite_(e: RemoveSiteEvent) {
     this.actionMenuModel_ = e.detail;
     this.$.confirmRemoveSite.get().showModal();
   }
 
-  onConfirmRemoveSite_(e: Event) {
+  private onConfirmRemoveSite_(e: Event) {
     const {index, actionScope, origin, isPartitioned} = this.actionMenuModel_!;
     const siteGroupToUpdate = this.filteredList_[index];
 
diff --git a/chrome/browser/resources/settings/site_settings/site_data.ts b/chrome/browser/resources/settings/site_settings/site_data.ts
index 9b8663db..32a805e 100644
--- a/chrome/browser/resources/settings/site_settings/site_data.ts
+++ b/chrome/browser/resources/settings/site_settings/site_data.ts
@@ -252,7 +252,7 @@
   /**
    * Shows a dialog to confirm the deletion of multiple sites.
    */
-  onRemoveShowingSitesTap_(e: Event) {
+  private onRemoveShowingSitesTap_(e: Event) {
     e.preventDefault();
     this.$.confirmDeleteDialog.showModal();
   }
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts
index de4cda3..c7032006 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.ts
+++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -135,7 +135,7 @@
   // Called by ReadAnythingPageHandler via callback router. //
   ////////////////////////////////////////////////////////////
 
-  showContent_(contentNodes: ContentNode[]) {
+  private showContent_(contentNodes: ContentNode[]) {
     const shadowRoot: ShadowRoot|null = this.shadowRoot;
     if (!shadowRoot) {
       return;
@@ -162,7 +162,7 @@
     }
   }
 
-  updateFontName_(newFontName: string) {
+  private updateFontName_(newFontName: string) {
     // Validate that the given font name is a valid choice, or use the default.
     const validFontName = this.validFontNames.find(
         (f: {name: string, cssClass: string}) => f.name === newFontName);
diff --git a/chrome/browser/resources/tab_search/app.ts b/chrome/browser/resources/tab_search/app.ts
index f93fd1f..94f23d7 100644
--- a/chrome/browser/resources/tab_search/app.ts
+++ b/chrome/browser/resources/tab_search/app.ts
@@ -609,7 +609,7 @@
     }
   }
 
-  announceA11y_(text: string) {
+  private announceA11y_(text: string) {
     IronA11yAnnouncer.requestAvailability();
     this.dispatchEvent(new CustomEvent(
         'iron-announce', {bubbles: true, composed: true, detail: {text}}));
diff --git a/chrome/browser/resources/tab_search/infinite_list.ts b/chrome/browser/resources/tab_search/infinite_list.ts
index ba8c863..cfb720b8 100644
--- a/chrome/browser/resources/tab_search/infinite_list.ts
+++ b/chrome/browser/resources/tab_search/infinite_list.ts
@@ -170,7 +170,7 @@
     }
   }
 
-  ensureTemplatized_() {
+  private ensureTemplatized_() {
     // The user provided light-dom template(s) to use when stamping DOM items.
     const templates = this.querySelectorAll('template');
     assert(templates.length > 0, 'At least one template must be provided');
diff --git a/chrome/browser/resources/tab_search/tab_search_item.ts b/chrome/browser/resources/tab_search/tab_search_item.ts
index 7d6b721..74ef7df 100644
--- a/chrome/browser/resources/tab_search/tab_search_item.ts
+++ b/chrome/browser/resources/tab_search/tab_search_item.ts
@@ -166,7 +166,7 @@
     }
   }
 
-  ariaLabelForText_(tabData: TabData): string {
+  private ariaLabelForText_(tabData: TabData): string {
     return ariaLabel(tabData);
   }
 
diff --git a/chrome/browser/resources/tab_strip/drag_manager.ts b/chrome/browser/resources/tab_strip/drag_manager.ts
index bced64a..63040d4 100644
--- a/chrome/browser/resources/tab_strip/drag_manager.ts
+++ b/chrome/browser/resources/tab_strip/drag_manager.ts
@@ -259,8 +259,8 @@
     this.element_.setDraggedOut(false);
   }
 
-  shouldOffsetIndexForGroup_(dragOverElement: TabElement|
-                             TabGroupElement): boolean {
+  private shouldOffsetIndexForGroup_(dragOverElement: TabElement|
+                                     TabGroupElement): boolean {
     // Since TabGroupElements do not have any TabElements, they need to offset
     // the index for any elements that come after it as if there is at least
     // one element inside of it.
diff --git a/chrome/browser/resources/welcome/signin_view.ts b/chrome/browser/resources/welcome/signin_view.ts
index 4c844fe..4403e16b 100644
--- a/chrome/browser/resources/welcome/signin_view.ts
+++ b/chrome/browser/resources/welcome/signin_view.ts
@@ -26,7 +26,6 @@
 
 const SigninViewElementBase = NavigationMixin(PolymerElement);
 
-/** @polymer */
 export class SigninViewElement extends SigninViewElementBase {
   static get is() {
     return 'signin-view';
@@ -71,8 +70,7 @@
     this.signinViewProxy_.recordNavigatedAway();
   }
 
-  /** private */
-  onSignInClick_() {
+  private onSignInClick_() {
     this.finalized_ = true;
     this.signinViewProxy_.recordSignIn();
     this.welcomeBrowserProxy_.handleActivateSignIn(null);
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
index 4570c7c..cc5dd93 100644
--- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
+++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -236,6 +236,11 @@
   if (reason == REASON_DOWNLOAD_DESTROYED)
     return absl::nullopt;
 
+  // If the download already has a scanning response attached, there is no need
+  // to try and upload it again.
+  if (item_->GetUserData(enterprise_connectors::ScanResult::kKey))
+    return absl::nullopt;
+
   // If the download is considered dangerous, don't upload the binary to show
   // a warning to the user ASAP.
   if (reason == REASON_DOWNLOAD_DANGEROUS ||
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn
index e9fab797..8a0aaa4c 100644
--- a/chrome/browser/safety_check/android/BUILD.gn
+++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -94,7 +94,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckMediatorTest.java" ]
   deps = [
     ":java",
@@ -123,7 +122,6 @@
     "//content/public/android:content_full_java",
     "//content/public/common:trust_tokens_mojo_bindings_java",
     "//third_party/android_deps:guava_android_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/signin/services/android/BUILD.gn b/chrome/browser/signin/services/android/BUILD.gn
index c7168470..b20bdd51 100644
--- a/chrome/browser/signin/services/android/BUILD.gn
+++ b/chrome/browser/signin/services/android/BUILD.gn
@@ -82,7 +82,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheUnitTest.java",
     "junit/src/org/chromium/chrome/browser/signin/services/WebSigninBridgeTest.java",
@@ -97,7 +96,6 @@
     "//chrome/test/android:chrome_java_unit_test_support",
     "//components/signin/public/android:java",
     "//components/signin/public/android:signin_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/storage/shared_storage_browsertest.cc b/chrome/browser/storage/shared_storage_browsertest.cc
index d61f9ef4..f0c9ba31 100644
--- a/chrome/browser/storage/shared_storage_browsertest.cc
+++ b/chrome/browser/storage/shared_storage_browsertest.cc
@@ -327,8 +327,11 @@
       content::EvalJs(GetActiveWebContents(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html", "fenced_frames/title1.html",
-          "fenced_frames/title2.html"], {data: {'mockResult': 1}});
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {report_event: "click",
+              report_url: "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 1}});
     )");
 
   if (!SuccessExpected()) {
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn
index 0766f17f..8962660 100644
--- a/chrome/browser/tab/BUILD.gn
+++ b/chrome/browser/tab/BUILD.gn
@@ -146,7 +146,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/chrome/browser/tab/CurrentTabObserverTest.java",
     "java/src/org/chromium/chrome/browser/tab/TabAssociatedAppTest.java",
@@ -160,7 +159,6 @@
     "//base:base_junit_test_support",
     "//chrome/browser/preferences:java",
     "//content/public/android:content_full_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/chrome/browser/tab_group/BUILD.gn b/chrome/browser/tab_group/BUILD.gn
index 06c28a0..46be5066 100644
--- a/chrome/browser/tab_group/BUILD.gn
+++ b/chrome/browser/tab_group/BUILD.gn
@@ -22,8 +22,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java",
     "junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupTitleUtilsUnitTest.java",
@@ -36,7 +34,6 @@
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/junit",
diff --git a/chrome/browser/tabmodel/BUILD.gn b/chrome/browser/tabmodel/BUILD.gn
index 2790067..35eba07f 100644
--- a/chrome/browser/tabmodel/BUILD.gn
+++ b/chrome/browser/tabmodel/BUILD.gn
@@ -67,8 +67,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserverUnitTest.java",
     "android/java/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerTest.java",
@@ -83,7 +81,6 @@
     "//chrome/browser/tab:java",
     "//chrome/browser/tabmodel:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/junit",
diff --git a/chrome/browser/tabpersistence/BUILD.gn b/chrome/browser/tabpersistence/BUILD.gn
index f6d3d66..d6cba176 100644
--- a/chrome/browser/tabpersistence/BUILD.gn
+++ b/chrome/browser/tabpersistence/BUILD.gn
@@ -21,7 +21,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManagerUnitTest.java" ]
   deps = [
     ":java",
@@ -31,7 +30,6 @@
     "//base/test:test_support_java",
     "//chrome/browser/tab:java",
     "//chrome/test/android:chrome_java_unit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/junit",
   ]
diff --git a/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManager.java b/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManager.java
index 908a17c..f327674 100644
--- a/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManager.java
+++ b/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManager.java
@@ -9,13 +9,10 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import org.chromium.base.FeatureList;
 import org.chromium.base.Log;
 import org.chromium.base.StreamUtil;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.crypto.CipherFactory;
-import org.chromium.chrome.browser.flags.CachedFeatureFlags;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tab.TabState;
@@ -225,13 +222,7 @@
         }
     }
 
-    public static byte[] getContentStateByteArray(final ByteBuffer passedBuffer) {
-        ByteBuffer buffer = passedBuffer;
-        // Use local ByteBuffer (backed by same byte[] to mitigate crbug.com/1297894)
-        if (FeatureList.isInitialized()
-                && CachedFeatureFlags.isEnabled(ChromeFeatureList.CRITICAL_PERSISTED_TAB_DATA)) {
-            buffer = buffer.asReadOnlyBuffer();
-        }
+    public static byte[] getContentStateByteArray(final ByteBuffer buffer) {
         byte[] contentsStateBytes = new byte[buffer.limit()];
         buffer.rewind();
         buffer.get(contentsStateBytes);
@@ -251,7 +242,9 @@
         // Create the byte array from contentsState before opening the FileOutputStream, in case
         // contentsState.buffer is an instance of MappedByteBuffer that is mapped to
         // the tab state file.
-        byte[] contentsStateBytes = getContentStateByteArray(state.contentsState.buffer());
+        // Use local ByteBuffer (backed by same byte[] to mitigate crbug.com/1297894)
+        byte[] contentsStateBytes =
+                getContentStateByteArray(state.contentsState.buffer().asReadOnlyBuffer());
 
         DataOutputStream dataOutputStream = null;
         FileOutputStream fileOutputStream = null;
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index fd3c36b..fd4e656 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -97,7 +97,7 @@
 // changed default theme assets, if you need themes to recreate their generated
 // images (which are cached), if you changed how missing values are
 // generated, or if you changed any constants.
-const int kThemePackVersion = 101;
+const int kThemePackVersion = 102;
 
 // IDs that are in the DataPack won't clash with the positive integer
 // uint16_t. kHeaderID should always have the maximum value because we want the
@@ -1605,8 +1605,8 @@
         omnibox_background_color, toolbar_color);
     SetColor(TP::COLOR_OMNIBOX_BACKGROUND, omnibox_background_color);
   } else {
-    omnibox_background_color =
-        TP::GetDefaultColor(TP::COLOR_OMNIBOX_BACKGROUND, false);
+    // TODO(pkasting): This should be shared with the omnibox color mixer.
+    omnibox_background_color = gfx::kGoogleGrey100;
   }
   SkColor omnibox_text_color;
   if (GetColor(TP::COLOR_OMNIBOX_TEXT, &omnibox_text_color)) {
diff --git a/chrome/browser/themes/increased_contrast_theme_supplier.cc b/chrome/browser/themes/increased_contrast_theme_supplier.cc
index 2b4f4df..9f3c731 100644
--- a/chrome/browser/themes/increased_contrast_theme_supplier.cc
+++ b/chrome/browser/themes/increased_contrast_theme_supplier.cc
@@ -32,8 +32,6 @@
         COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO:
       *color = SK_ColorBLACK;
       return true;
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF:
-    case ThemeProperties::COLOR_INFOBAR:
     case ThemeProperties::COLOR_NTP_BACKGROUND:
     case ThemeProperties::COLOR_TOOLBAR:
     case ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE:
@@ -52,10 +50,7 @@
     case ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_ACTIVE:
       *color = is_dark_mode_ ? SK_ColorDKGRAY : SK_ColorLTGRAY;
       return true;
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR:
-    case ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR:
     case ThemeProperties::COLOR_LOCATION_BAR_BORDER:
-    case ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR:
     case ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR:
     case ThemeProperties::COLOR_TOOLBAR_TEXT:
       *color = foreground;
diff --git a/chrome/browser/themes/theme_helper.cc b/chrome/browser/themes/theme_helper.cc
index 0ea1acb..0d4a1ec07 100644
--- a/chrome/browser/themes/theme_helper.cc
+++ b/chrome/browser/themes/theme_helper.cc
@@ -223,11 +223,6 @@
     int id,
     bool incognito,
     const CustomThemeSupplier* theme_supplier) const {
-  const absl::optional<SkColor> omnibox_color =
-      GetOmniboxColor(id, incognito, theme_supplier);
-  if (omnibox_color.has_value())
-    return omnibox_color.value();
-
   // For backward compat with older themes, some newer colors are generated from
   // older ones if they are missing.
   const auto get_frame_color = [this, incognito, theme_supplier](bool active) {
@@ -236,8 +231,6 @@
   };
   switch (id) {
     case TP::COLOR_BOOKMARK_BAR_BACKGROUND:
-    case TP::COLOR_DOWNLOAD_SHELF:
-    case TP::COLOR_INFOBAR:
     case TP::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE:
     case TP::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE:
       return GetColor(TP::COLOR_TOOLBAR, incognito, theme_supplier);
@@ -268,48 +261,6 @@
     case TP::COLOR_TAB_STROKE_FRAME_INACTIVE:
       return GetColor(TP::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_INACTIVE, incognito,
                       theme_supplier);
-    case TP::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR:
-      return color_utils::AlphaBlend(
-          GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, incognito, theme_supplier),
-          GetColor(TP::COLOR_DOWNLOAD_SHELF, incognito, theme_supplier),
-          SkAlpha{0x3A});
-    case TP::COLOR_STATUS_BUBBLE_ACTIVE:
-      return GetColor(TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, incognito,
-                      theme_supplier);
-    case TP::COLOR_STATUS_BUBBLE_INACTIVE:
-      return GetColor(TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE,
-                      incognito, theme_supplier);
-    case TP::COLOR_STATUS_BUBBLE_TEXT_ACTIVE:
-      return GetColor(TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE, incognito,
-                      theme_supplier);
-    case TP::COLOR_STATUS_BUBBLE_TEXT_INACTIVE:
-      return GetColor(TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE,
-                      incognito, theme_supplier);
-    case TP::COLOR_OMNIBOX_BACKGROUND: {
-      // TODO(http://crbug.com/878664): Enable for all cases.
-      if (!IsCustomTheme(theme_supplier))
-        break;
-      constexpr float kMinOmniboxToolbarContrast = 1.3f;
-      const SkColor toolbar_color =
-          GetColor(TP::COLOR_TOOLBAR, incognito, theme_supplier);
-      const SkColor endpoint_color =
-          color_utils::GetEndpointColorWithMinContrast(toolbar_color);
-      const SkColor blend_target =
-          (color_utils::GetContrastRatio(toolbar_color, endpoint_color) >=
-           kMinOmniboxToolbarContrast)
-              ? endpoint_color
-              : color_utils::GetColorWithMaxContrast(endpoint_color);
-      return color_utils::BlendForMinContrast(toolbar_color, toolbar_color,
-                                              blend_target,
-                                              kMinOmniboxToolbarContrast)
-          .color;
-    }
-    case TP::COLOR_OMNIBOX_TEXT:
-      // TODO(http://crbug.com/878664): Enable for all cases.
-      if (!IsCustomTheme(theme_supplier))
-        break;
-      return color_utils::GetColorWithMaxContrast(
-          GetColor(TP::COLOR_OMNIBOX_BACKGROUND, incognito, theme_supplier));
     case TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE:
       return color_utils::HSLShift(get_frame_color(/*active=*/true),
                                    GetTint(ThemeProperties::TINT_BACKGROUND_TAB,
@@ -366,12 +317,6 @@
       return SkColorSetA(
           GetColor(TP::COLOR_TOOLBAR_INK_DROP, incognito, theme_supplier),
           0x20);
-    case TP::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR:
-      return color_utils::AlphaBlend(
-          GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, incognito, theme_supplier),
-          GetColor(TP::COLOR_INFOBAR, incognito, theme_supplier),
-          SkAlpha{0x3A});
-    case TP::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR:
     case TP::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR:
       return color_utils::AlphaBlend(
           GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, incognito, theme_supplier),
@@ -442,163 +387,3 @@
 
   return image;
 }
-
-absl::optional<SkColor> ThemeHelper::GetOmniboxColor(
-    int id,
-    bool incognito,
-    const CustomThemeSupplier* theme_supplier) const {
-  // The base colors are not computed; avoid infinite recursion.  COLOR_TOOLBAR
-  // must also be excluded since it's used in the base definition of
-  // COLOR_OMNIBOX_BACKGROUND.
-  if (id == TP::COLOR_OMNIBOX_BACKGROUND || id == TP::COLOR_OMNIBOX_TEXT ||
-      id == TP::COLOR_TOOLBAR) {
-    return absl::nullopt;
-  }
-
-  // Compute the two base colors, |bg| and |fg|.
-  SkColor bg =
-      GetColor(TP::COLOR_OMNIBOX_BACKGROUND, incognito, theme_supplier);
-  SkColor fg = GetColor(TP::COLOR_OMNIBOX_TEXT, incognito, theme_supplier);
-
-  // Certain output cases are based on inverted bg/fg.
-  const bool high_contrast =
-      theme_supplier && theme_supplier->get_theme_type() ==
-                            ui::ColorProviderManager::ThemeInitializerSupplier::
-                                ThemeType::kIncreasedContrast;
-  const bool invert =
-      high_contrast &&
-      (id == TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_ICON_SELECTED ||
-       id == TP::COLOR_OMNIBOX_RESULTS_URL_SELECTED);
-  const auto blend_for_min_contrast =
-      [&](SkColor fg, SkColor bg, absl::optional<SkColor> hc_fg = absl::nullopt,
-          absl::optional<float> contrast_ratio = absl::nullopt) {
-        // If high contrast is on, increase the minimum contrast ratio.
-        // TODO(pkasting): Ideally we could do this in the base
-        // BlendForMinContrast() function.
-        const float ratio = contrast_ratio.value_or(
-            high_contrast ? 6.0f : color_utils::kMinimumReadableContrastRatio);
-        return color_utils::BlendForMinContrast(fg, bg, hc_fg, ratio).color;
-      };
-  if (invert) {
-    // Given a color with some contrast against the opposite endpoint, returns a
-    // color with that same contrast against the nearby endpoint.
-    auto invert_color = [&](SkColor fg) {
-      const auto bg = color_utils::GetColorWithMaxContrast(fg);
-      const auto inverted_bg = color_utils::GetColorWithMaxContrast(bg);
-      const float contrast = color_utils::GetContrastRatio(fg, bg);
-      return blend_for_min_contrast(fg, inverted_bg, absl::nullopt, contrast);
-    };
-    fg = invert_color(fg);
-    bg = invert_color(bg);
-  }
-  const bool dark = color_utils::IsDark(bg);
-
-  // All remaining colors can be built atop the two base colors.
-  const auto results_bg_color = [&]() {
-    return color_utils::GetColorWithMaxContrast(fg);
-  };
-  const auto bg_hovered_color = [&]() {
-    return color_utils::BlendTowardMaxContrast(bg, 0x0A);
-  };
-  const auto results_bg_hovered_color = [&]() {
-    return color_utils::BlendTowardMaxContrast(results_bg_color(), 0x1A);
-  };
-  const auto negative_text_color = [&](SkColor bg) {
-    return blend_for_min_contrast(
-        dark ? gfx::kGoogleRed300 : gfx::kGoogleRed600, bg);
-  };
-  const auto positive_text_color = [&](SkColor bg) {
-    return blend_for_min_contrast(
-        dark ? gfx::kGoogleGreen300 : gfx::kGoogleGreen700, bg);
-  };
-  const auto secondary_text_color = [&](SkColor bg) {
-    return blend_for_min_contrast(
-        // In the color pipeline world, this color is kColorDisabledForeground.
-        blend_for_min_contrast(
-            gfx::kGoogleGrey600,
-            dark ? SkColorSetRGB(0x29, 0x2A, 0x2D) : SK_ColorWHITE,
-            dark ? gfx::kGoogleGrey200 : gfx::kGoogleGrey900),
-        bg);
-  };
-  const auto url_color = [&](SkColor bg) {
-    return blend_for_min_contrast(
-        gfx::kGoogleBlue500, bg,
-        dark ? gfx::kGoogleBlue050 : gfx::kGoogleBlue900);
-  };
-  const auto results_bg_selected_color = [&]() {
-    return color_utils::BlendTowardMaxContrast(results_bg_color(), 0x1A);
-  };
-  const auto blend_with_clamped_contrast = [&](SkColor bg) {
-    return blend_for_min_contrast(fg, fg, blend_for_min_contrast(bg, bg));
-  };
-  switch (id) {
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED:
-      return fg;
-    case TP::COLOR_OMNIBOX_BACKGROUND_HOVERED:
-      return bg_hovered_color();
-    case TP::COLOR_OMNIBOX_RESULTS_BG:
-      return results_bg_color();
-    case TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED:
-      return results_bg_selected_color();
-    case TP::COLOR_OMNIBOX_BUBBLE_OUTLINE:
-      return dark ? gfx::kGoogleGrey100
-                  : SkColorSetA(gfx::kGoogleGrey900, 0x24);
-    case TP::COLOR_OMNIBOX_TEXT_DIMMED:
-      return blend_with_clamped_contrast(bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED:
-      return blend_with_clamped_contrast(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED:
-      return blend_with_clamped_contrast(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE:
-      return negative_text_color(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED:
-      return negative_text_color(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE:
-      return positive_text_color(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED:
-      return positive_text_color(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY:
-      return secondary_text_color(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED:
-      return secondary_text_color(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_ICON:
-      return blend_for_min_contrast(color_utils::DeriveDefaultIconColor(fg),
-                                    results_bg_color());
-    case TP::COLOR_OMNIBOX_RESULTS_ICON_SELECTED:
-      return blend_for_min_contrast(color_utils::DeriveDefaultIconColor(fg),
-                                    results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED:
-      return results_bg_hovered_color();
-    case TP::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE:
-    case TP::COLOR_OMNIBOX_SELECTED_KEYWORD:
-      if (dark)
-        return gfx::kGoogleGrey100;
-      [[fallthrough]];
-    case TP::COLOR_OMNIBOX_RESULTS_URL:
-      return url_color(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_URL_SELECTED:
-      return url_color(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_RESULTS_BUTTON_BORDER:
-      return color_utils::BlendTowardMaxContrast(bg, gfx::kGoogleGreyAlpha400);
-    case TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP:
-      return color_utils::GetColorWithMaxContrast(results_bg_hovered_color());
-    case TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED:
-      return color_utils::GetColorWithMaxContrast(results_bg_selected_color());
-    case TP::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT:
-    case TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE:
-      return blend_for_min_contrast(
-          dark ? gfx::kGoogleGrey500 : gfx::kGoogleGrey700, bg_hovered_color());
-    case TP::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS:
-      return blend_for_min_contrast(
-          dark ? gfx::kGoogleRed300 : gfx::kGoogleRed600, bg_hovered_color());
-    default:
-      return absl::nullopt;
-  }
-}
diff --git a/chrome/browser/themes/theme_helper.h b/chrome/browser/themes/theme_helper.h
index a38310327..9af2cf6 100644
--- a/chrome/browser/themes/theme_helper.h
+++ b/chrome/browser/themes/theme_helper.h
@@ -118,14 +118,6 @@
                            bool incognito,
                            const CustomThemeSupplier* theme_supplier) const;
 
-  // Given a theme property ID |id|, returns the corresponding omnibox color
-  // overridden by the system theme.  Returns absl::nullopt if the color is not
-  // overridden, or if |id| does not correspond to an omnibox color.
-  absl::optional<SkColor> GetOmniboxColor(
-      int id,
-      bool incognito,
-      const CustomThemeSupplier* theme_supplier) const;
-
   SkColor GetTabGroupColor(int id,
                            bool incognito,
                            const CustomThemeSupplier* theme_supplier) const;
diff --git a/chrome/browser/themes/theme_helper_win.cc b/chrome/browser/themes/theme_helper_win.cc
index 9d7a4b4..2e0bcff9 100644
--- a/chrome/browser/themes/theme_helper_win.cc
+++ b/chrome/browser/themes/theme_helper_win.cc
@@ -40,8 +40,6 @@
     case ThemeProperties::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE:
     case ThemeProperties::
         COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO:
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF:
-    case ThemeProperties::COLOR_INFOBAR:
     case ThemeProperties::COLOR_TOOLBAR:
       system_theme_color = ui::NativeTheme::SystemThemeColor::kWindow;
       break;
@@ -57,32 +55,7 @@
       system_theme_color = ui::NativeTheme::SystemThemeColor::kWindowText;
       break;
 
-    // Button Background
-    case ThemeProperties::COLOR_OMNIBOX_BACKGROUND:
-    case ThemeProperties::COLOR_OMNIBOX_BACKGROUND_HOVERED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_BG:
-      system_theme_color = ui::NativeTheme::SystemThemeColor::kButtonFace;
-      break;
-
     // Button Text Foreground
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR:
-    case ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR:
-    case ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE:
-    case ThemeProperties::
-        COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_URL:
-    case ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT:
-    case ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_SECURE:
-    case ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS:
-    case ThemeProperties::COLOR_OMNIBOX_SELECTED_KEYWORD:
-    case ThemeProperties::COLOR_OMNIBOX_TEXT:
-    case ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED:
-    case ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR:
     case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO:
     case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE:
@@ -99,21 +72,9 @@
       if (!base::FeatureList::IsEnabled(
               views::features::kEnablePlatformHighContrastInkDrop))
         return false;
-      [[fallthrough]];
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_HOVERED:
       system_theme_color = ui::NativeTheme::SystemThemeColor::kHighlight;
       break;
 
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED:
-      *color = color_utils::GetColorWithMaxContrast(
-          ui::NativeTheme::GetInstanceForNativeUi()
-              ->GetSystemThemeColor(
-                  ui::NativeTheme::SystemThemeColor::kHighlight)
-              .value());
-      return true;
-
     // Highlight/Selected Text Foreground
     case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_HOVERED:
     case ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_PRESSED:
@@ -123,13 +84,6 @@
             ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON, color);
       }
       [[fallthrough]];
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED:
-    case ThemeProperties::COLOR_OMNIBOX_RESULTS_URL_SELECTED:
     case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE:
       system_theme_color = ui::NativeTheme::SystemThemeColor::kHighlightText;
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc
index 52560d8..47ada71 100644
--- a/chrome/browser/themes/theme_properties.cc
+++ b/chrome/browser/themes/theme_properties.cc
@@ -62,16 +62,10 @@
           GetLightModeColor(ThemeProperties::COLOR_FRAME_ACTIVE),
           ThemeProperties::GetDefaultTint(ThemeProperties::TINT_FRAME_INACTIVE,
                                           false));
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF:
-    case ThemeProperties::COLOR_INFOBAR:
     case ThemeProperties::COLOR_TOOLBAR:
     case ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE:
       return SK_ColorWHITE;
-    case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND:
-      return gfx::kGoogleGrey300;
-    case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND:
-      return gfx::kGoogleGrey050;
     case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE:
     case ThemeProperties::COLOR_TOOLBAR_TEXT:
@@ -92,8 +86,6 @@
       return gfx::kGoogleGrey100;
 
     // Properties not stored in theme pack.
-    case ThemeProperties::COLOR_STATUS_BUBBLE_SHADOW:
-      return SkColorSetA(SK_ColorBLACK, 0x1E);
     case ThemeProperties::COLOR_TAB_STROKE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_STROKE_FRAME_INACTIVE:
     case ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_ACTIVE:
@@ -109,12 +101,6 @@
     case ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_FOREGROUND:
     case ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_DEFAULT_BUTTON_BACKGROUND:
       return SK_ColorWHITE;
-    // TODO(http://crbug.com/878664): Remove COLOR_OMNIBOX_xxx when these are
-    // consistently autogenerated.
-    case ThemeProperties::COLOR_OMNIBOX_TEXT:
-      return gfx::kGoogleGrey900;
-    case ThemeProperties::COLOR_OMNIBOX_BACKGROUND:
-      return gfx::kGoogleGrey100;
 
     case ThemeProperties::COLOR_FRAME_ACTIVE_INCOGNITO:
     case ThemeProperties::COLOR_FRAME_INACTIVE_INCOGNITO:
@@ -154,16 +140,11 @@
           GetLightModeColor(ThemeProperties::COLOR_FRAME_ACTIVE),
           ThemeProperties::GetDefaultTint(ThemeProperties::TINT_FRAME_INACTIVE,
                                           true));
-    case ThemeProperties::COLOR_DOWNLOAD_SHELF:
-    case ThemeProperties::COLOR_INFOBAR:
     case ThemeProperties::COLOR_TOOLBAR:
     case ThemeProperties::COLOR_NTP_BACKGROUND:
     case ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE:
     case ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE:
       return SkColorSetRGB(0x35, 0x36, 0x3A);
-    case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND:
-      return gfx::kGoogleGrey700;
-    case ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND:
     case ThemeProperties::COLOR_NTP_SHORTCUT:
       return gfx::kGoogleGrey900;
     case ThemeProperties::COLOR_TOOLBAR_TEXT:
@@ -175,12 +156,6 @@
       return gfx::kGoogleGrey400;
     case ThemeProperties::COLOR_NTP_LINK:
       return gfx::kGoogleBlue300;
-    // TODO(http://crbug.com/878664): Remove COLOR_OMNIBOX_xxx when these are
-    // consistently autogenerated.
-    case ThemeProperties::COLOR_OMNIBOX_TEXT:
-      return SK_ColorWHITE;
-    case ThemeProperties::COLOR_OMNIBOX_BACKGROUND:
-      return gfx::kGoogleGrey900;
     default:
       return absl::nullopt;
   }
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h
index 14a6806..8c4634c1 100644
--- a/chrome/browser/themes/theme_properties.h
+++ b/chrome/browser/themes/theme_properties.h
@@ -129,32 +129,6 @@
     // shelf.
     COLOR_TOOLBAR_VERTICAL_SEPARATOR,
 
-    // Colors used for various 'shelves' and 'bars'.
-    // Download shelf colors.
-    COLOR_DOWNLOAD_SHELF,
-    COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR,
-
-    // Infobar colors.
-    COLOR_INFOBAR,
-    COLOR_INFOBAR_CONTENT_AREA_SEPARATOR,
-
-    COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR,
-
-    // Status bubble colors.
-    COLOR_STATUS_BUBBLE_ACTIVE,
-    COLOR_STATUS_BUBBLE_INACTIVE,
-    COLOR_STATUS_BUBBLE_SHADOW,
-    COLOR_STATUS_BUBBLE_TEXT_ACTIVE,
-    COLOR_STATUS_BUBBLE_TEXT_INACTIVE,
-
-    // /!\ If you make any changes to this enum, you must also increment
-    // kThemePackVersion in browser_theme_pack.cc, or else themes will display
-    // incorrectly.
-
-    // Colors used when displaying hover cards.
-    COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND,
-    COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND,
-
     // Colors used for the active tab.
     COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE,
     COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE,
@@ -208,38 +182,6 @@
     COLOR_FEATURE_PROMO_BUBBLE_DEFAULT_BUTTON_FOREGROUND,
     COLOR_FEATURE_PROMO_BUBBLE_FOREGROUND,
 
-    // /!\ If you make any changes to this enum, you must also increment
-    // kThemePackVersion in browser_theme_pack.cc, or else themes will display
-    // incorrectly.
-
-    COLOR_OMNIBOX_BACKGROUND_HOVERED,
-    COLOR_OMNIBOX_SELECTED_KEYWORD,
-    COLOR_OMNIBOX_TEXT_DIMMED,
-    COLOR_OMNIBOX_RESULTS_BG,
-    COLOR_OMNIBOX_RESULTS_BG_HOVERED,
-    COLOR_OMNIBOX_RESULTS_BG_SELECTED,
-    COLOR_OMNIBOX_RESULTS_BUTTON_BORDER,
-    COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP,
-    COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED,
-    COLOR_OMNIBOX_RESULTS_TEXT_DIMMED,
-    COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED,
-    COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE,
-    COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED,
-    COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE,
-    COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED,
-    COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY,
-    COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED,
-    COLOR_OMNIBOX_RESULTS_TEXT_SELECTED,
-    COLOR_OMNIBOX_RESULTS_ICON,
-    COLOR_OMNIBOX_RESULTS_ICON_SELECTED,
-    COLOR_OMNIBOX_RESULTS_URL,
-    COLOR_OMNIBOX_RESULTS_URL_SELECTED,
-    COLOR_OMNIBOX_BUBBLE_OUTLINE,
-    COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE,
-    COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT,
-    COLOR_OMNIBOX_SECURITY_CHIP_SECURE,
-    COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS,
-
     // Colors used for the Bookmark bar
     COLOR_BOOKMARK_BAR_BACKGROUND,
     // If COLOR_TOOLBAR_BUTTON_ICON is defined in the custom theme, that color
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index 4c3ae66..c76d5a5 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -102,9 +102,6 @@
       {TP::COLOR_BOOKMARK_SEPARATOR, kColorBookmarkBarSeparator},
       {TP::COLOR_BOOKMARK_TEXT, kColorBookmarkBarForeground},
       {TP::COLOR_CONTROL_BUTTON_BACKGROUND, kColorCaptionButtonBackground},
-      {TP::COLOR_DOWNLOAD_SHELF, kColorDownloadShelfBackground},
-      {TP::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR,
-       kColorDownloadShelfContentAreaSeparator},
       {TP::COLOR_FEATURE_PROMO_BUBBLE_BACKGROUND,
        kColorFeaturePromoBubbleBackground},
       {TP::COLOR_FEATURE_PROMO_BUBBLE_BUTTON_BORDER,
@@ -119,13 +116,6 @@
        kColorFeaturePromoBubbleForeground},
       {TP::COLOR_FLYING_INDICATOR_BACKGROUND, kColorFlyingIndicatorBackground},
       {TP::COLOR_FLYING_INDICATOR_FOREGROUND, kColorFlyingIndicatorForeground},
-      {TP::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND,
-       kColorTabHoverCardBackground},
-      {TP::COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND,
-       kColorTabHoverCardForeground},
-      {TP::COLOR_INFOBAR, kColorInfoBarBackground},
-      {TP::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR,
-       kColorInfoBarContentAreaSeparator},
       {TP::COLOR_LOCATION_BAR_BORDER, kColorLocationBarBorder},
       {TP::COLOR_LOCATION_BAR_BORDER_OPAQUE, kColorLocationBarBorderOpaque},
       {TP::COLOR_NTP_BACKGROUND, kColorNewTabPageBackground},
@@ -136,66 +126,10 @@
       {TP::COLOR_NTP_SHORTCUT, kColorNewTabPageMostVisitedTileBackground},
       {TP::COLOR_NTP_TEXT, kColorNewTabPageText},
       {TP::COLOR_NTP_TEXT_LIGHT, kColorNewTabPageTextLight},
-      {TP::COLOR_OMNIBOX_BACKGROUND, kColorOmniboxBackground},
-      {TP::COLOR_OMNIBOX_BACKGROUND_HOVERED, kColorOmniboxBackgroundHovered},
-      {TP::COLOR_OMNIBOX_BUBBLE_OUTLINE, kColorOmniboxBubbleOutline},
-      {TP::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE,
-       kColorOmniboxBubbleOutlineExperimentalKeywordMode},
-      {TP::COLOR_OMNIBOX_SELECTED_KEYWORD, kColorOmniboxKeywordSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_BG, kColorOmniboxResultsBackground},
-      {TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED,
-       kColorOmniboxResultsBackgroundHovered},
-      {TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED,
-       kColorOmniboxResultsBackgroundSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_BUTTON_BORDER,
-       kColorOmniboxResultsButtonBorder},
-      {TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP,
-       kColorOmniboxResultsButtonInkDrop},
-      {TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED,
-       kColorOmniboxResultsButtonInkDropSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_ICON, kColorOmniboxResultsIcon},
-      {TP::COLOR_OMNIBOX_RESULTS_ICON_SELECTED,
-       kColorOmniboxResultsIconSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED, kColorOmniboxResultsTextDimmed},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED,
-       kColorOmniboxResultsTextDimmedSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE,
-       kColorOmniboxResultsTextNegative},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED,
-       kColorOmniboxResultsTextNegativeSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE,
-       kColorOmniboxResultsTextPositive},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED,
-       kColorOmniboxResultsTextPositiveSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY,
-       kColorOmniboxResultsTextSecondary},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED,
-       kColorOmniboxResultsTextSecondarySelected},
-      {TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED,
-       kColorOmniboxResultsTextSelected},
-      {TP::COLOR_OMNIBOX_RESULTS_URL, kColorOmniboxResultsUrl},
-      {TP::COLOR_OMNIBOX_RESULTS_URL_SELECTED, kColorOmniboxResultsUrlSelected},
-      {TP::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS,
-       kColorOmniboxSecurityChipDangerous},
-      {TP::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT,
-       kColorOmniboxSecurityChipDefault},
-      {TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE, kColorOmniboxSecurityChipSecure},
-      {TP::COLOR_OMNIBOX_TEXT, kColorOmniboxText},
-      {TP::COLOR_OMNIBOX_TEXT_DIMMED, kColorOmniboxTextDimmed},
       {TP::COLOR_FRAME_CAPTION_ACTIVE, kColorFrameCaptionActive},
       {TP::COLOR_FRAME_CAPTION_INACTIVE, kColorFrameCaptionInactive},
       {TP::COLOR_FRAME_ACTIVE, ui::kColorFrameActive},
       {TP::COLOR_FRAME_INACTIVE, ui::kColorFrameInactive},
-      {TP::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR,
-       kColorSidePanelContentAreaSeparator},
-      {TP::COLOR_STATUS_BUBBLE_ACTIVE, kColorStatusBubbleBackgroundFrameActive},
-      {TP::COLOR_STATUS_BUBBLE_INACTIVE,
-       kColorStatusBubbleBackgroundFrameInactive},
-      {TP::COLOR_STATUS_BUBBLE_TEXT_ACTIVE,
-       kColorStatusBubbleForegroundFrameActive},
-      {TP::COLOR_STATUS_BUBBLE_TEXT_INACTIVE,
-       kColorStatusBubbleForegroundFrameInactive},
-      {TP::COLOR_STATUS_BUBBLE_SHADOW, kColorStatusBubbleShadow},
       {TP::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE,
        kColorTabBackgroundActiveFrameActive},
       {TP::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE,
diff --git a/chrome/browser/themes/theme_service_linux_unittest.cc b/chrome/browser/themes/theme_service_linux_unittest.cc
index f111417..978ecb6 100644
--- a/chrome/browser/themes/theme_service_linux_unittest.cc
+++ b/chrome/browser/themes/theme_service_linux_unittest.cc
@@ -142,10 +142,10 @@
     for (auto color_id : theme_service::test::kTestColorIds) {
       if (ignored_color_ids.contains(color_id))
         continue;
-      std::string error_message =
-          base::StrCat({"GTK theme ", theme, ": ",
-                        theme_service::test::ColorIdToString(color_id),
-                        " has mismatched values"});
+      std::string error_message = base::StrCat(
+          {"GTK theme ", theme, ": ",
+           theme_service::test::ThemePropertiesColorToString(color_id),
+           " has mismatched values"});
       theme_service::test::TestOriginalAndRedirectedColorMatched(
           theme_provider, color_id, error_message);
     }
diff --git a/chrome/browser/themes/theme_service_test_utils.cc b/chrome/browser/themes/theme_service_test_utils.cc
index e99733a..45089b8 100644
--- a/chrome/browser/themes/theme_service_test_utils.cc
+++ b/chrome/browser/themes/theme_service_test_utils.cc
@@ -28,7 +28,19 @@
                                   SkColorGetB(color));
 }
 
-std::string ColorIdToString(int id) {
+std::string ColorIdToString(ui::ColorId id) {
+#define E(color_id, theme_property_id, ...) {color_id, #color_id},
+#define E_CPONLY(color_id, ...) {color_id, #color_id},
+
+  static constexpr const auto kMap =
+      base::MakeFixedFlatMap<ui::ColorId, const char*>({CHROME_COLOR_IDS});
+
+#undef E
+#undef E_CPONLY
+  return kMap.find(id)->second;
+}
+
+std::string ThemePropertiesColorToString(int id) {
 #define E(color_id, theme_property_id, ...) \
   {theme_property_id, #theme_property_id},
 #define E_CPONLY(color_id, ...)
@@ -38,9 +50,8 @@
 
 #undef E
 #undef E_CPONLY
-  constexpr char kPrefix[] = "ThemeProperties::";
-
   std::string id_str = kMap.find(id)->second;
+  constexpr char kPrefix[] = "ThemeProperties::";
   return base::StartsWith(id_str, kPrefix) ? id_str.substr(strlen(kPrefix))
                                            : id_str;
 }
diff --git a/chrome/browser/themes/theme_service_test_utils.h b/chrome/browser/themes/theme_service_test_utils.h
index e2f2bf7..2885e0f 100644
--- a/chrome/browser/themes/theme_service_test_utils.h
+++ b/chrome/browser/themes/theme_service_test_utils.h
@@ -23,10 +23,7 @@
 #undef E_CPONLY
 
 static constexpr const auto kColorTolerances = base::MakeFixedFlatMap<int, int>(
-    {{ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY, 1},
-     {ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED, 1},
-     {ThemeProperties::COLOR_STATUS_BUBBLE_INACTIVE, 1},
-     {ThemeProperties::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE, 1},
+    {{ThemeProperties::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE, 1},
      {ThemeProperties::COLOR_TAB_STROKE_FRAME_INACTIVE, 1},
      {ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_FRAME_INACTIVE, 1},
      {ThemeProperties::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE, 1}});
@@ -41,7 +38,8 @@
 
 std::ostream& operator<<(std::ostream& os, PrintableSkColor printable_color);
 
-std::string ColorIdToString(int id);
+std::string ColorIdToString(ui::ColorId id);
+std::string ThemePropertiesColorToString(int id);
 
 std::pair<PrintableSkColor, PrintableSkColor> GetOriginalAndRedirected(
     const ui::ThemeProvider& theme_provider,
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc
index 923b9820..a843bb8 100644
--- a/chrome/browser/themes/theme_service_unittest.cc
+++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -46,6 +46,7 @@
 #include "extensions/browser/uninstall_reason.h"
 #include "extensions/common/extension.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/color/color_provider.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/native_theme/test_native_theme.h"
@@ -172,16 +173,6 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void set_theme_supplier(ThemeService* theme_service,
-                          scoped_refptr<CustomThemeSupplier> theme_supplier) {
-    theme_service->theme_supplier_ = theme_supplier;
-  }
-
-  SkColor GetColor(ThemeService* theme_service, int id, bool incognito) const {
-    return theme_service->theme_helper_.GetColor(
-        id, incognito, theme_service->GetThemeSupplier());
-  }
-
   bool IsExtensionDisabled(const std::string& id) const {
     return registry_->GetExtensionById(id,
                                        extensions::ExtensionRegistry::DISABLED);
@@ -193,12 +184,12 @@
   raw_ptr<ThemeService> theme_service_ = nullptr;
 };
 
-class ThemeProviderRedirectedEquivalenceTest
+class ColorProviderTest
     : public ThemeServiceTest,
       public testing::WithParamInterface<
           std::tuple<ui::NativeTheme::ColorScheme, ContrastMode, SystemTheme>> {
  public:
-  ThemeProviderRedirectedEquivalenceTest() = default;
+  ColorProviderTest() = default;
 
   // ThemeServiceTest:
   void SetUp() override {
@@ -302,6 +293,13 @@
            SystemThemeToString(std::get<SystemTheme>(param_tuple));
   }
 
+  SkColor GetColor(ui::ColorId id) const {
+    const auto* const color_provider =
+        ui::ColorProviderManager::Get().GetColorProviderFor(
+            native_theme_->GetColorProviderKey(nullptr));
+    return color_provider->GetColor(id);
+  }
+
  private:
   static std::string ColorSchemeToString(ui::NativeTheme::ColorScheme scheme) {
     switch (scheme) {
@@ -338,14 +336,14 @@
 
 INSTANTIATE_TEST_SUITE_P(
     ,
-    ThemeProviderRedirectedEquivalenceTest,
+    ColorProviderTest,
     ::testing::Combine(::testing::Values(ui::NativeTheme::ColorScheme::kLight,
                                          ui::NativeTheme::ColorScheme::kDark),
                        ::testing::Values(ContrastMode::kNonHighContrast,
                                          ContrastMode::kHighContrast),
                        ::testing::Values(SystemTheme::kDefault,
                                          SystemTheme::kCustom)),
-    ThemeProviderRedirectedEquivalenceTest::ParamInfoToString);
+    ColorProviderTest::ParamInfoToString);
 
 // Installs then uninstalls a theme and makes sure that the ThemeService
 // reverts to the default theme after the uninstall.
@@ -563,91 +561,84 @@
   EXPECT_FALSE(service_->IsExtensionEnabled(scoper.extension_id()));
 }
 
-TEST_F(ThemeServiceTest, OmniboxContrast) {
-  using TP = ThemeProperties;
-  for (bool dark : {false, true}) {
-    test_native_theme_.SetDarkMode(dark);
-    for (bool high_contrast : {false, true}) {
-      set_theme_supplier(
-          theme_service_,
-          high_contrast ? base::MakeRefCounted<IncreasedContrastThemeSupplier>(
-                              &test_native_theme_)
-                        : nullptr);
-      constexpr int contrasting_ids[][2] = {
-          {TP::COLOR_OMNIBOX_RESULTS_ICON, TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_ICON,
-           TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_ICON_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED, TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE,
-           TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE,
-           TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE,
-           TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE,
-           TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY,
-           TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY,
-           TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_RESULTS_URL, TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_RESULTS_URL, TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_RESULTS_URL_SELECTED,
-           TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED},
-          {TP::COLOR_OMNIBOX_BUBBLE_OUTLINE, TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE,
-           TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT,
-           TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT,
-           TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE,
-           TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE,
-           TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS,
-           TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS,
-           TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-          {TP::COLOR_OMNIBOX_SELECTED_KEYWORD, TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_SELECTED_KEYWORD,
-           TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-          {TP::COLOR_OMNIBOX_TEXT, TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_TEXT, TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-          {TP::COLOR_OMNIBOX_TEXT, TP::COLOR_OMNIBOX_RESULTS_BG},
-          {TP::COLOR_OMNIBOX_TEXT, TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED},
-          {TP::COLOR_OMNIBOX_TEXT_DIMMED, TP::COLOR_OMNIBOX_BACKGROUND},
-          {TP::COLOR_OMNIBOX_TEXT_DIMMED, TP::COLOR_OMNIBOX_BACKGROUND_HOVERED},
-      };
-      auto check_sufficient_contrast = [&](int id1, int id2) {
+TEST_P(ColorProviderTest, OmniboxContrast) {
+#if BUILDFLAG(IS_WIN)
+  // TODO(crbug.com/1336315): Windows platform high contrast colors are not
+  // sufficiently high-contrast to pass this test.
+  if (std::get<ContrastMode>(GetParam()) == ContrastMode::kHighContrast)
+    return;
+#endif
+
+  constexpr ui::ColorId contrasting_ids[][2] = {
+      {kColorOmniboxResultsIcon, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsIcon, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsIconSelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsTextSelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsTextDimmed, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsTextDimmed, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsTextDimmedSelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsTextNegative, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsTextNegative, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsTextNegativeSelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsTextPositive, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsTextPositive, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsTextPositiveSelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsTextSecondary, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsTextSecondary,
+       kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsTextSecondarySelected,
+       kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxResultsUrl, kColorOmniboxResultsBackground},
+      {kColorOmniboxResultsUrl, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxResultsUrlSelected, kColorOmniboxResultsBackgroundSelected},
+      {kColorOmniboxBubbleOutline, kColorOmniboxResultsBackground},
+      {kColorOmniboxBubbleOutlineExperimentalKeywordMode,
+       kColorOmniboxResultsBackground},
+      {kColorOmniboxSecurityChipDefault, kColorOmniboxBackground},
+      {kColorOmniboxSecurityChipDefault, kColorOmniboxBackgroundHovered},
+      {kColorOmniboxSecurityChipSecure, kColorOmniboxBackground},
+      {kColorOmniboxSecurityChipSecure, kColorOmniboxBackgroundHovered},
+      {kColorOmniboxSecurityChipDangerous, kColorOmniboxBackground},
+      {kColorOmniboxSecurityChipDangerous, kColorOmniboxBackgroundHovered},
+      {kColorOmniboxKeywordSelected, kColorOmniboxBackground},
+      {kColorOmniboxKeywordSelected, kColorOmniboxBackgroundHovered},
+      {kColorOmniboxText, kColorOmniboxBackground},
+      {kColorOmniboxText, kColorOmniboxBackgroundHovered},
+      {kColorOmniboxText, kColorOmniboxResultsBackground},
+      {kColorOmniboxText, kColorOmniboxResultsBackgroundHovered},
+      {kColorOmniboxTextDimmed, kColorOmniboxBackground},
+      {kColorOmniboxTextDimmed, kColorOmniboxBackgroundHovered},
+  };
+  auto check_sufficient_contrast =
+      [&](ui::ColorId id1, ui::ColorId id2,
+          float expected_contrast_ratio =
+              color_utils::kMinimumReadableContrastRatio) {
+        const theme_service::test::PrintableSkColor color1{GetColor(id1)};
+        const theme_service::test::PrintableSkColor color2{GetColor(id2)};
         const float contrast =
-            color_utils::GetContrastRatio(GetColor(theme_service_, id1, dark),
-                                          GetColor(theme_service_, id2, dark));
-        EXPECT_GE(contrast, color_utils::kMinimumReadableContrastRatio)
-            << "Dark: " << dark << " High contrast: " << high_contrast
-            << " ID 1: " << id1 << " ID2: " << id2;
+            color_utils::GetContrastRatio(color1.color, color2.color);
+        EXPECT_GE(contrast, expected_contrast_ratio)
+            << "Color 1: " << theme_service::test::ColorIdToString(id1) << " - "
+            << color1
+            << "\nColor 2: " << theme_service::test::ColorIdToString(id2)
+            << " - " << color2;
       };
-      for (const int* ids : contrasting_ids)
-        check_sufficient_contrast(ids[0], ids[1]);
-      if (high_contrast)
-        check_sufficient_contrast(TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED,
-                                  TP::COLOR_OMNIBOX_RESULTS_BG);
-    }
+  for (const ui::ColorId* ids : contrasting_ids)
+    check_sufficient_contrast(ids[0], ids[1]);
+#if !BUILDFLAG(USE_GTK) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+  // TODO(crbug.com/1336796): GTK and LaCrOS do not have a sufficiently
+  // high-contrast selected row color to pass this test.
+  if (std::get<ContrastMode>(GetParam()) == ContrastMode::kHighContrast) {
+    check_sufficient_contrast(kColorOmniboxResultsBackgroundSelected,
+                              kColorOmniboxResultsBackground,
+                              color_utils::kMinimumVisibleContrastRatio);
   }
+#endif
 }
 
 TEST_F(ThemeServiceTest, NativeIncreasedContrastChanged) {
@@ -762,7 +753,7 @@
   EXPECT_TRUE(registry_->GetInstalledExtension(scoper.extension_id()));
 }
 
-TEST_P(ThemeProviderRedirectedEquivalenceTest, GetColor) {
+TEST_P(ColorProviderTest, GetColor) {
 #if BUILDFLAG(IS_LINUX)
   const auto param_tuple = GetParam();
   const auto color_scheme = std::get<ui::NativeTheme::ColorScheme>(param_tuple);
@@ -780,9 +771,9 @@
       ThemeService::GetThemeProviderForProfile(profile());
 
   for (auto color_id : theme_service::test::kTestColorIds) {
-    std::string error_message =
-        base::StrCat({theme_service::test::ColorIdToString(color_id),
-                      " has mismatched values"});
+    std::string error_message = base::StrCat(
+        {theme_service::test::ThemePropertiesColorToString(color_id),
+         " has mismatched values"});
     theme_service::test::TestOriginalAndRedirectedColorMatched(
         theme_provider, color_id, error_message);
   }
diff --git a/chrome/browser/ui/android/appmenu/internal/BUILD.gn b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
index 53df19b0..b86e1c4 100644
--- a/chrome/browser/ui/android/appmenu/internal/BUILD.gn
+++ b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
@@ -111,12 +111,10 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuPopupPositionTest.java" ]
   deps = [
     ":java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/ui/android/autofill/internal/BUILD.gn b/chrome/browser/ui/android/autofill/internal/BUILD.gn
index 09d374f..49543b2 100644
--- a/chrome/browser/ui/android/autofill/internal/BUILD.gn
+++ b/chrome/browser/ui/android/autofill/internal/BUILD.gn
@@ -54,7 +54,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogBridgeTest.java",
     "java/src/org/chromium/chrome/browser/ui/autofill/AuthenticatorSelectionDialogTest.java",
diff --git a/chrome/browser/ui/android/default_browser_promo/BUILD.gn b/chrome/browser/ui/android/default_browser_promo/BUILD.gn
index b360025..f303b9e 100644
--- a/chrome/browser/ui/android/default_browser_promo/BUILD.gn
+++ b/chrome/browser/ui/android/default_browser_promo/BUILD.gn
@@ -23,13 +23,11 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/chrome/browser/ui/default_browser_promo/DefaultBrowserPromoUtilsTest.java" ]
   deps = [
     ":java",
     "//base:base_java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/chrome/browser/ui/android/layouts/BUILD.gn b/chrome/browser/ui/android/layouts/BUILD.gn
index 9d0e4b7c..f7d4269 100644
--- a/chrome/browser/ui/android/layouts/BUILD.gn
+++ b/chrome/browser/ui/android/layouts/BUILD.gn
@@ -53,8 +53,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/layouts/CompositorModelChangeProcessorUnitTest.java",
     "java/src/org/chromium/chrome/browser/layouts/FilterLayoutStateObserverTest.java",
@@ -67,7 +65,6 @@
     "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/chrome/browser/ui/android/logo/BUILD.gn b/chrome/browser/ui/android/logo/BUILD.gn
index 9365bca..40547d5 100644
--- a/chrome/browser/ui/android/logo/BUILD.gn
+++ b/chrome/browser/ui/android/logo/BUILD.gn
@@ -75,8 +75,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/logo/LogoLoadHelperUnitTest.java",
   ]
@@ -94,7 +92,6 @@
     "//components/search_engines/android:java",
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/ui/android/native_page/BUILD.gn b/chrome/browser/ui/android/native_page/BUILD.gn
index dd53c11b..2153ef2 100644
--- a/chrome/browser/ui/android/native_page/BUILD.gn
+++ b/chrome/browser/ui/android/native_page/BUILD.gn
@@ -22,8 +22,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/ui/native_page/NativePageTest.java",
   ]
@@ -31,7 +29,6 @@
   deps = [
     ":java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
   ]
 }
diff --git a/chrome/browser/ui/android/night_mode/BUILD.gn b/chrome/browser/ui/android/night_mode/BUILD.gn
index a9ed3097..b181f48b 100644
--- a/chrome/browser/ui/android/night_mode/BUILD.gn
+++ b/chrome/browser/ui/android/night_mode/BUILD.gn
@@ -105,7 +105,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/chrome/browser/night_mode/AutoDarkFeedbackSourceUnitTest.java",
     "java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeControllerUnitTest.java",
@@ -135,7 +134,6 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//testing/android/junit:junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn
index f4dae72..091852e 100644
--- a/chrome/browser/ui/android/omnibox/BUILD.gn
+++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -349,8 +349,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java",
     "java/src/org/chromium/chrome/browser/omnibox/AutocompleteStateUnitTest.java",
@@ -429,7 +427,6 @@
     "//content/public/test/android:content_java_test_support",
     "//testing/android/junit:junit_test_support",
     "//third_party/android_deps:material_design_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
diff --git a/chrome/browser/ui/android/signin/BUILD.gn b/chrome/browser/ui/android/signin/BUILD.gn
index 3545aa5..f898529 100644
--- a/chrome/browser/ui/android/signin/BUILD.gn
+++ b/chrome/browser/ui/android/signin/BUILD.gn
@@ -136,7 +136,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/chrome/browser/ui/signin/ConfirmSyncDataStateMachineTest.java",
     "junit/src/org/chromium/chrome/browser/ui/signin/SigninPromoControllerTest.java",
@@ -164,7 +163,6 @@
     "//components/signin/public/android:signin_java_test_support",
     "//components/user_prefs/android:java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_fragment_fragment_java",
     "//third_party/androidx:androidx_test_core_java",
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn
index ede8733..80aa685 100644
--- a/chrome/browser/ui/android/toolbar/BUILD.gn
+++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -270,8 +270,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonControllerUnitTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveButtonActionMenuCoordinatorTest.java",
@@ -279,6 +277,7 @@
     "java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarFeaturesTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarStatePredictorTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerUnitTest.java",
+    "java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonTest.java",
@@ -321,7 +320,6 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:guava_android_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_core_java",
@@ -340,7 +338,6 @@
   sources = [
     "java/src/org/chromium/chrome/browser/toolbar/ToolbarProgressBarTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarPreferenceFragmentTest.java",
-    "java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java",
   ]
 
   deps = [
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
index 0e2ce6e..7537c80 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
@@ -11,6 +11,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.os.Looper;
+
 import androidx.test.filters.SmallTest;
 
 import org.hamcrest.Matchers;
@@ -21,14 +23,13 @@
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowLooper;
 
 import org.chromium.base.MathUtils;
 import org.chromium.base.supplier.ObservableSupplierImpl;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.UiThreadTest;
-import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Criteria;
-import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
 import org.chromium.chrome.browser.toolbar.load_progress.LoadProgressProperties.CompletionState;
@@ -36,13 +37,13 @@
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.url.GURL;
+import org.chromium.url.JUnitTestGURLs;
 
 /** Unit tests for LoadProgressMediator. */
-@RunWith(BaseJUnit4ClassRunner.class)
-@Batch(Batch.UNIT_TESTS)
+@RunWith(BaseRobolectricTestRunner.class)
 public class LoadProgressMediatorTest {
-    private static final GURL URL_1 = new GURL("http://starting.url");
-    private static final GURL NATIVE_PAGE_URL = new GURL("chrome-native://newtab");
+    private static final GURL URL_1 = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL);
+    private static final GURL NATIVE_PAGE_URL = JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL);
 
     @Mock
     private Tab mTab;
@@ -56,6 +57,7 @@
     private LoadProgressMediator mMediator;
     private TabObserver mTabObserver;
     private ObservableSupplierImpl<Tab> mTabSupplier;
+    private ShadowLooper mShadowLooper;
 
     @Before
     public void setUp() {
@@ -63,6 +65,7 @@
         mModel = TestThreadUtils.runOnUiThreadBlockingNoException(
                 () -> new PropertyModel(LoadProgressProperties.ALL_KEYS));
         when(mTab.getUrl()).thenReturn(URL_1);
+        mShadowLooper = Shadows.shadowOf(Looper.getMainLooper());
     }
 
     private void initMediator() {
@@ -76,33 +79,31 @@
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void loadRegularPage() {
         initMediator();
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
 
         NavigationHandle navigation =
                 new NavigationHandle(0, URL_1, GURL.emptyGURL(), GURL.emptyGURL(), true, false,
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         mTabObserver.onLoadProgressChanged(mTab, 0.1f);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 0.1f, MathUtils.EPSILON);
+        assertEquals(0.1f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         mTabObserver.onLoadProgressChanged(mTab, 1.0f);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 1.0f, MathUtils.EPSILON);
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DO_ANIMATE);
+        assertEquals(1.0f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
+        assertEquals(CompletionState.FINISHED_DO_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void switchToLoadingTab() {
         initMediator();
         doReturn(true).when(mTab2).isLoading();
@@ -111,13 +112,12 @@
         verify(mTab2, times(1)).addObserver(any());
 
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 0.1f, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(0.1f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void switchToLoadedTab() {
         initMediator();
         NavigationHandle navigation =
@@ -125,19 +125,18 @@
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         mTabSupplier.set(mTab2);
         verify(mTab2, times(1)).addObserver(any());
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void loadNativePage() {
         initMediator();
         doReturn(0.1f).when(mTab).getProgress();
@@ -146,19 +145,18 @@
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 0.1f, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(0.1f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         navigation = new NavigationHandle(0, NATIVE_PAGE_URL, GURL.emptyGURL(), GURL.emptyGURL(),
                 true, false, false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void switchToTabWithNativePage() {
         initMediator();
         NavigationHandle navigation =
@@ -166,22 +164,21 @@
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         when(mTab2.getUrl()).thenReturn(NATIVE_PAGE_URL);
         mTabSupplier.set(mTab2);
         verify(mTab2, times(1)).addObserver(any());
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void pageCrashes() {
         initMediator();
         NavigationHandle navigation =
@@ -189,66 +186,67 @@
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
 
         mTabObserver.onCrash(mTab);
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
-                LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(LoadProgressMediator.MINIMUM_LOAD_PROGRESS,
+                mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void testSwapWebContents() {
         initMediator();
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        // Swap web contents after loading started and finished. As loading already happened we
+        // simulate the load events.
         mTabObserver.onWebContentsSwapped(mTab, true, true);
         assertEquals(
-                mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 0, MathUtils.EPSILON);
+                CompletionState.UNFINISHED, mModel.get(LoadProgressProperties.COMPLETION_STATE));
+        assertEquals(0, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
+
+        // Ensure load events are simulated as expected.
         float expectedProgress = LoadProgressSimulator.PROGRESS_INCREMENT;
         while (expectedProgress < 1.0f + LoadProgressSimulator.PROGRESS_INCREMENT) {
+            mShadowLooper.runOneTask();
             final float nextExpectedProgress = expectedProgress;
-            CriteriaHelper.pollUiThreadNested(() -> {
-                Criteria.checkThat((double) mModel.get(LoadProgressProperties.PROGRESS),
-                        Matchers.closeTo(nextExpectedProgress, MathUtils.EPSILON));
-            }, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, 0);
+            Criteria.checkThat((double) mModel.get(LoadProgressProperties.PROGRESS),
+                    Matchers.closeTo(nextExpectedProgress, MathUtils.EPSILON));
             expectedProgress += LoadProgressSimulator.PROGRESS_INCREMENT;
         }
 
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DO_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DO_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
     }
 
     @Test
     @SmallTest
-    @UiThreadTest
     public void testSameDocumentLoad_afterFinishedLoading() {
         initMediator();
         GURL gurl = URL_1;
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DONT_ANIMATE);
+        assertEquals(CompletionState.FINISHED_DONT_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
 
         NavigationHandle navigation =
                 new NavigationHandle(0, gurl, GURL.emptyGURL(), GURL.emptyGURL(), true, false,
                         false, null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         mTabObserver.onLoadProgressChanged(mTab, 1.0f);
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 1.0f, MathUtils.EPSILON);
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DO_ANIMATE);
+        assertEquals(1.0f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
+        assertEquals(CompletionState.FINISHED_DO_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
         NavigationHandle sameDocNav =
                 new NavigationHandle(0, gurl, GURL.emptyGURL(), GURL.emptyGURL(), true, true, false,
                         null, 0, false, false, false, false, 0, false, false);
         mTabObserver.onDidStartNavigation(mTab, sameDocNav);
 
-        assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 1.0f, MathUtils.EPSILON);
-        assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
-                CompletionState.FINISHED_DO_ANIMATE);
+        assertEquals(1.0f, mModel.get(LoadProgressProperties.PROGRESS), MathUtils.EPSILON);
+        assertEquals(CompletionState.FINISHED_DO_ANIMATE,
+                mModel.get(LoadProgressProperties.COMPLETION_STATE));
     }
 }
diff --git a/chrome/browser/ui/android/webid/internal/BUILD.gn b/chrome/browser/ui/android/webid/internal/BUILD.gn
index 3e60f4d..ca55134 100644
--- a/chrome/browser/ui/android/webid/internal/BUILD.gn
+++ b/chrome/browser/ui/android/webid/internal/BUILD.gn
@@ -66,8 +66,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java" ]
 
   deps = [
@@ -82,7 +80,6 @@
     "//components/favicon/android:java",
     "//components/image_fetcher:java",
     "//components/url_formatter/android:url_formatter_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/ui/ash/clipboard_history_browsertest.cc b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
index 1f8f8e47..21418b4 100644
--- a/chrome/browser/ui/ash/clipboard_history_browsertest.cc
+++ b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
@@ -45,6 +45,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/dns/mock_host_resolver.h"
+#include "ui/base/clipboard/clipboard_data.h"
 #include "ui/base/clipboard/clipboard_monitor.h"
 #include "ui/base/clipboard/clipboard_non_backed.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
@@ -241,6 +242,20 @@
   return true;
 }
 
+// Returns whether the clipboard buffer matches clipboard history's first item.
+// If clipboard history is empty, returns whether the clipboard buffer is empty.
+bool VerifyClipboardBufferAndHistoryInSync() {
+  auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread();
+  if (!clipboard)
+    return false;
+
+  ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory);
+  const auto* const clipboard_data = clipboard->GetClipboardData(&data_dst);
+  const auto& items = GetClipboardItems();
+  return items.empty() ? clipboard_data == nullptr
+                       : items.front().data() == *clipboard_data;
+}
+
 }  // namespace
 
 class ClipboardHistoryBrowserTest : public ash::LoginManagerTest {
@@ -625,13 +640,21 @@
   ASSERT_EQ(2, GetContextMenu()->GetMenuItemsCount());
 
   // Delete the second menu item.
-  ClickAtDeleteButton(/*index=*/1);
+  {
+    ScopedClipboardHistoryListUpdateWaiter scoped_waiter;
+    ClickAtDeleteButton(/*index=*/1);
+  }
   EXPECT_EQ(1, GetContextMenu()->GetMenuItemsCount());
   EXPECT_TRUE(VerifyClipboardTextData({"B"}));
+  EXPECT_TRUE(VerifyClipboardBufferAndHistoryInSync());
 
   // Delete the last menu item. Verify that the menu is closed.
-  ClickAtDeleteButton(/*index=*/0);
+  {
+    ScopedClipboardHistoryListUpdateWaiter scoped_waiter;
+    ClickAtDeleteButton(/*index=*/0);
+  }
   EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
+  EXPECT_TRUE(VerifyClipboardBufferAndHistoryInSync());
 
   // No menu shows because of the empty clipboard history.
   ShowContextMenuViaAccelerator(/*wait_for_selection=*/false);
@@ -654,23 +677,35 @@
 
   // Select the first menu item via key then delete it. Verify the menu and the
   // clipboard history.
-  PressAndRelease(ui::KeyboardCode::VKEY_BACK);
+  {
+    ScopedClipboardHistoryListUpdateWaiter scoped_waiter;
+    PressAndRelease(ui::KeyboardCode::VKEY_BACK);
+  }
   EXPECT_EQ(2, GetContextMenu()->GetMenuItemsCount());
   EXPECT_TRUE(VerifyClipboardTextData({"B", "A"}));
+  EXPECT_TRUE(VerifyClipboardBufferAndHistoryInSync());
 
   histogram_tester.ExpectTotalCount(
       "Ash.ClipboardHistory.ContextMenu.DisplayFormatDeleted", 1);
 
   // Select the second menu item via key then delete it. Verify the menu and the
   // clipboard history.
-  PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_NONE);
-  PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE);
+  {
+    ScopedClipboardHistoryListUpdateWaiter scoped_waiter;
+    PressAndRelease(ui::KeyboardCode::VKEY_DOWN, ui::EF_NONE);
+    PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE);
+  }
   EXPECT_EQ(1, GetContextMenu()->GetMenuItemsCount());
   EXPECT_TRUE(VerifyClipboardTextData({"B"}));
+  EXPECT_TRUE(VerifyClipboardBufferAndHistoryInSync());
 
   // Delete the last item. Verify that the menu is closed.
-  PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE);
+  {
+    ScopedClipboardHistoryListUpdateWaiter scoped_waiter;
+    PressAndRelease(ui::KeyboardCode::VKEY_BACK, ui::EF_NONE);
+  }
   EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
+  EXPECT_TRUE(VerifyClipboardBufferAndHistoryInSync());
 
   // Trigger the accelerator of opening the clipboard history menu. No menu
   // shows because of the empty history data.
diff --git a/chrome/browser/ui/ash/shelf/lacros_app_window.cc b/chrome/browser/ui/ash/shelf/lacros_app_window.cc
index 48fe36b..721c2bd 100644
--- a/chrome/browser/ui/ash/shelf/lacros_app_window.cc
+++ b/chrome/browser/ui/ash/shelf/lacros_app_window.cc
@@ -44,9 +44,6 @@
       gfx::Size(kWindowIconSizeDips, kWindowIconSizeDips));
   views::NativeWidgetAura::AssignIconToAuraWindow(GetNativeWindow(),
                                                   window_icon, app_icon);
-  auto* win = widget->GetNativeWindow();
-  if (win)
-    win->SetProperty(aura::client::kUseWindowBoundsForShadow, false);
 }
 
 LacrosAppWindow::~LacrosAppWindow() = default;
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h
index 5db6f618c..4df8433 100644
--- a/chrome/browser/ui/color/chrome_color_id.h
+++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -53,13 +53,12 @@
   E_CPONLY(kColorDownloadItemForegroundSafe) \
   E_CPONLY(kColorDownloadItemProgressRingBackground) \
   E_CPONLY(kColorDownloadItemProgressRingForeground) \
-  E(kColorDownloadShelfBackground, ThemeProperties::COLOR_DOWNLOAD_SHELF) \
+  E_CPONLY(kColorDownloadShelfBackground) \
   E_CPONLY(kColorDownloadShelfButtonBackground) \
   E_CPONLY(kColorDownloadShelfButtonText) \
   E_CPONLY(kColorDownloadShelfButtonIcon) \
   E_CPONLY(kColorDownloadShelfButtonIconDisabled) \
-  E(kColorDownloadShelfContentAreaSeparator, \
-    ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR) \
+  E_CPONLY(kColorDownloadShelfContentAreaSeparator) \
   E_CPONLY(kColorDownloadShelfForeground) \
   E_CPONLY(kColorDownloadStartedAnimationForeground) \
   E_CPONLY(kColorDownloadToolbarButtonActive) \
@@ -111,11 +110,10 @@
   E(kColorFrameCaptionActive, ThemeProperties::COLOR_FRAME_CAPTION_ACTIVE) \
   E(kColorFrameCaptionInactive, ThemeProperties::COLOR_FRAME_CAPTION_INACTIVE) \
   /* InfoBar colors. */ \
-  E(kColorInfoBarBackground, ThemeProperties::COLOR_INFOBAR) \
+  E_CPONLY(kColorInfoBarBackground) \
   E_CPONLY(kColorInfoBarButtonIcon) \
   E_CPONLY(kColorInfoBarButtonIconDisabled) \
-  E(kColorInfoBarContentAreaSeparator, \
-    ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR) \
+  E_CPONLY(kColorInfoBarContentAreaSeparator) \
   E_CPONLY(kColorInfoBarForeground) \
   /* Intent Picker colors. */ \
   E_CPONLY(kColorIntentPickerItemBackgroundHovered) \
@@ -153,63 +151,39 @@
   /* Omnibox colors. */ \
   E_CPONLY(kColorOmniboxAnswerIconBackground) \
   E_CPONLY(kColorOmniboxAnswerIconForeground) \
-  E(kColorOmniboxBackground, ThemeProperties::COLOR_OMNIBOX_BACKGROUND) \
-  E(kColorOmniboxBackgroundHovered, \
-    ThemeProperties::COLOR_OMNIBOX_BACKGROUND_HOVERED) \
-  E(kColorOmniboxBubbleOutline, \
-    ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE) \
-  E(kColorOmniboxBubbleOutlineExperimentalKeywordMode, \
-    ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE) \
+  E_CPONLY(kColorOmniboxBackground) \
+  E_CPONLY(kColorOmniboxBackgroundHovered) \
+  E_CPONLY(kColorOmniboxBubbleOutline) \
+  E_CPONLY(kColorOmniboxBubbleOutlineExperimentalKeywordMode) \
   E_CPONLY(kColorOmniboxChipBackgroundLowVisibility) \
   E_CPONLY(kColorOmniboxChipBackgroundNormalVisibility) \
   E_CPONLY(kColorOmniboxChipForegroundLowVisibility) \
   E_CPONLY(kColorOmniboxChipForegroundNormalVisibility) \
-  E(kColorOmniboxKeywordSelected, \
-    ThemeProperties::COLOR_OMNIBOX_SELECTED_KEYWORD) \
-  E(kColorOmniboxResultsBackground, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BG) \
-  E(kColorOmniboxResultsBackgroundHovered, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_HOVERED) \
-  E(kColorOmniboxResultsBackgroundSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_SELECTED) \
-  E(kColorOmniboxResultsButtonBorder, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BUTTON_BORDER) \
-  E(kColorOmniboxResultsButtonInkDrop, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP) \
-  E(kColorOmniboxResultsButtonInkDropSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED) \
-  E(kColorOmniboxResultsIcon, ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON) \
-  E(kColorOmniboxResultsIconSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON_SELECTED) \
-  E(kColorOmniboxResultsTextDimmed, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED) \
-  E(kColorOmniboxResultsTextDimmedSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED) \
-  E(kColorOmniboxResultsTextNegative, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE) \
-  E(kColorOmniboxResultsTextNegativeSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED) \
-  E(kColorOmniboxResultsTextPositive, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE) \
-  E(kColorOmniboxResultsTextPositiveSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED) \
-  E(kColorOmniboxResultsTextSecondary, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY) \
-  E(kColorOmniboxResultsTextSecondarySelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED) \
-  E(kColorOmniboxResultsTextSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED) \
-  E(kColorOmniboxResultsUrl, ThemeProperties::COLOR_OMNIBOX_RESULTS_URL) \
-  E(kColorOmniboxResultsUrlSelected, \
-    ThemeProperties::COLOR_OMNIBOX_RESULTS_URL_SELECTED) \
-  E(kColorOmniboxSecurityChipDangerous, \
-    ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS) \
-  E(kColorOmniboxSecurityChipDefault, \
-    ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT) \
-  E(kColorOmniboxSecurityChipSecure, \
-    ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_SECURE) \
-  E(kColorOmniboxText, ThemeProperties::COLOR_OMNIBOX_TEXT) \
-  E(kColorOmniboxTextDimmed, ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED) \
+  E_CPONLY(kColorOmniboxKeywordSelected) \
+  E_CPONLY(kColorOmniboxResultsBackground) \
+  E_CPONLY(kColorOmniboxResultsBackgroundHovered) \
+  E_CPONLY(kColorOmniboxResultsBackgroundSelected) \
+  E_CPONLY(kColorOmniboxResultsButtonBorder) \
+  E_CPONLY(kColorOmniboxResultsButtonInkDrop) \
+  E_CPONLY(kColorOmniboxResultsButtonInkDropSelected) \
+  E_CPONLY(kColorOmniboxResultsIcon) \
+  E_CPONLY(kColorOmniboxResultsIconSelected) \
+  E_CPONLY(kColorOmniboxResultsTextDimmed) \
+  E_CPONLY(kColorOmniboxResultsTextDimmedSelected) \
+  E_CPONLY(kColorOmniboxResultsTextNegative) \
+  E_CPONLY(kColorOmniboxResultsTextNegativeSelected) \
+  E_CPONLY(kColorOmniboxResultsTextPositive) \
+  E_CPONLY(kColorOmniboxResultsTextPositiveSelected) \
+  E_CPONLY(kColorOmniboxResultsTextSecondary) \
+  E_CPONLY(kColorOmniboxResultsTextSecondarySelected) \
+  E_CPONLY(kColorOmniboxResultsTextSelected) \
+  E_CPONLY(kColorOmniboxResultsUrl) \
+  E_CPONLY(kColorOmniboxResultsUrlSelected) \
+  E_CPONLY(kColorOmniboxSecurityChipDangerous) \
+  E_CPONLY(kColorOmniboxSecurityChipDefault) \
+  E_CPONLY(kColorOmniboxSecurityChipSecure) \
+  E_CPONLY(kColorOmniboxText) \
+  E_CPONLY(kColorOmniboxTextDimmed) \
   /* Page Info colors */ \
   E_CPONLY(kColorPageInfoChosenObjectDeleteButtonIcon) \
   E_CPONLY(kColorPageInfoChosenObjectDeleteButtonIconDisabled) \
@@ -261,16 +235,13 @@
   E_CPONLY(kColorScreenshotCapturedImageBorder) \
   /* Side panel colors. */ \
   E_CPONLY(kColorSidePanelBackground) \
-  E(kColorSidePanelContentAreaSeparator, \
-    ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR) \
+  E_CPONLY(kColorSidePanelContentAreaSeparator) \
   /* Status bubble colors. */ \
-  E(kColorStatusBubbleBackgroundFrameActive, \
-    ThemeProperties::COLOR_STATUS_BUBBLE_ACTIVE) \
-  E(kColorStatusBubbleBackgroundFrameInactive, \
-    ThemeProperties::COLOR_STATUS_BUBBLE_INACTIVE) \
+  E_CPONLY(kColorStatusBubbleBackgroundFrameActive) \
+  E_CPONLY(kColorStatusBubbleBackgroundFrameInactive) \
   E_CPONLY(kColorStatusBubbleForegroundFrameActive) \
   E_CPONLY(kColorStatusBubbleForegroundFrameInactive) \
-  E(kColorStatusBubbleShadow, ThemeProperties::COLOR_STATUS_BUBBLE_SHADOW) \
+  E_CPONLY(kColorStatusBubbleShadow) \
   /* Tab alert colors. */ \
   E_CPONLY(kColorTabAlertAudioPlayingActiveFrameActive) \
   E_CPONLY(kColorTabAlertAudioPlayingActiveFrameInactive) \
@@ -301,10 +272,8 @@
   E_CPONLY(kColorTabForegroundActiveFrameInactive) \
   E_CPONLY(kColorTabForegroundInactiveFrameActive) \
   E_CPONLY(kColorTabForegroundInactiveFrameInactive) \
-  E(kColorTabHoverCardBackground, \
-    ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND) \
-  E(kColorTabHoverCardForeground, \
-    ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND) \
+  E_CPONLY(kColorTabHoverCardBackground) \
+  E_CPONLY(kColorTabHoverCardForeground) \
   /* The colors used for tab groups in the tabstrip. */ \
   E_CPONLY(kColorTabGroupTabStripFrameActiveGrey) \
   E_CPONLY(kColorTabGroupTabStripFrameActiveBlue) \
diff --git a/chrome/browser/ui/extensions/extensions_dialogs.h b/chrome/browser/ui/extensions/extensions_dialogs.h
index 2a91a15..91493375 100644
--- a/chrome/browser/ui/extensions/extensions_dialogs.h
+++ b/chrome/browser/ui/extensions/extensions_dialogs.h
@@ -20,13 +20,13 @@
 namespace extensions {
 
 // Shows a dialog when an extension requires a refresh after gaining access to
-// the current site in order to run its blocked action. When the dialog is
-// accepted, `callback` is invoked. with a booleand indication whether the
-// checkbox (if shown) was checked by the user.
+// the current site in order to run its blocked action. The dialog content is
+// based on whether caller `is_updating_permissions`. When the dialog is
+// accepted, `callback` is invoked.
 void ShowBlockedActionDialog(Browser* browser,
                              const ExtensionId& extension_id,
-                             bool show_checkbox,
-                             base::OnceCallback<void(bool)> callback);
+                             bool is_updating_permissions,
+                             base::OnceClosure callback);
 
 #if BUILDFLAG(IS_CHROMEOS)
 
diff --git a/chrome/browser/ui/messages/android/BUILD.gn b/chrome/browser/ui/messages/android/BUILD.gn
index 77b8284..b104ee3 100644
--- a/chrome/browser/ui/messages/android/BUILD.gn
+++ b/chrome/browser/ui/messages/android/BUILD.gn
@@ -60,8 +60,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [ "java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarCollectionUnitTest.java" ]
 
   deps = [
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.cc b/chrome/browser/ui/omnibox/omnibox_theme.cc
index f5e753c..5cb19d09 100644
--- a/chrome/browser/ui/omnibox/omnibox_theme.cc
+++ b/chrome/browser/ui/omnibox/omnibox_theme.cc
@@ -6,99 +6,97 @@
 
 #include "base/notreached.h"
 #include "build/build_config.h"
-#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/color/chrome_color_id.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
-#include "ui/base/theme_provider.h"
+#include "ui/color/color_provider.h"
 #include "ui/gfx/color_palette.h"
 
 using TP = ThemeProperties;
 
 namespace {
 
-int GetThemePropertyId(OmniboxPart part, OmniboxPartState state) {
+ui::ColorId GetColorId(OmniboxPart part, OmniboxPartState state) {
   const bool selected = state == OmniboxPartState::SELECTED;
   switch (part) {
     case OmniboxPart::LOCATION_BAR_BACKGROUND:
-      return state == OmniboxPartState::HOVERED
-                 ? static_cast<int>(TP::COLOR_OMNIBOX_BACKGROUND_HOVERED)
-                 : static_cast<int>(TP::COLOR_OMNIBOX_BACKGROUND);
+      return state == OmniboxPartState::HOVERED ? kColorOmniboxBackgroundHovered
+                                                : kColorOmniboxBackground;
     case OmniboxPart::LOCATION_BAR_SELECTED_KEYWORD:
-      return TP::COLOR_OMNIBOX_SELECTED_KEYWORD;
+      return kColorOmniboxKeywordSelected;
     case OmniboxPart::RESULTS_BACKGROUND:
       switch (state) {
         case OmniboxPartState::NORMAL:
-          return TP::COLOR_OMNIBOX_RESULTS_BG;
+          return kColorOmniboxResultsBackground;
         case OmniboxPartState::HOVERED:
-          return TP::COLOR_OMNIBOX_RESULTS_BG_HOVERED;
+          return kColorOmniboxResultsBackgroundHovered;
         case OmniboxPartState::SELECTED:
-          return TP::COLOR_OMNIBOX_RESULTS_BG_SELECTED;
+          return kColorOmniboxResultsBackgroundSelected;
         default:
           NOTREACHED();
-          return TP::COLOR_OMNIBOX_RESULTS_BG;
+          return kColorOmniboxResultsBackground;
       }
     case OmniboxPart::LOCATION_BAR_CLEAR_ALL:
     case OmniboxPart::LOCATION_BAR_TEXT_DEFAULT:
-      return TP::COLOR_OMNIBOX_TEXT;
+      return kColorOmniboxText;
     case OmniboxPart::LOCATION_BAR_TEXT_DIMMED:
-      return TP::COLOR_OMNIBOX_TEXT_DIMMED;
+      return kColorOmniboxTextDimmed;
     case OmniboxPart::RESULTS_ICON:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_ICON_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_ICON;
+      return selected ? kColorOmniboxResultsIconSelected
+                      : kColorOmniboxResultsIcon;
     case OmniboxPart::RESULTS_TEXT_DEFAULT:
-      return selected ? int{TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED}
-                      : int{TP::COLOR_OMNIBOX_TEXT};
+      return selected ? kColorOmniboxResultsTextSelected : kColorOmniboxText;
     case OmniboxPart::RESULTS_TEXT_DIMMED:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED;
+      return selected ? kColorOmniboxResultsTextDimmedSelected
+                      : kColorOmniboxResultsTextDimmed;
     case OmniboxPart::RESULTS_TEXT_NEGATIVE:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_TEXT_NEGATIVE;
+      return selected ? kColorOmniboxResultsTextNegativeSelected
+                      : kColorOmniboxResultsTextNegative;
     case OmniboxPart::RESULTS_TEXT_POSITIVE:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_TEXT_POSITIVE;
+      return selected ? kColorOmniboxResultsTextPositiveSelected
+                      : kColorOmniboxResultsTextPositive;
     case OmniboxPart::RESULTS_TEXT_SECONDARY:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_TEXT_SECONDARY;
+      return selected ? kColorOmniboxResultsTextSecondarySelected
+                      : kColorOmniboxResultsTextSecondary;
     case OmniboxPart::RESULTS_TEXT_URL:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_URL_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_URL;
+      return selected ? kColorOmniboxResultsUrlSelected
+                      : kColorOmniboxResultsUrl;
     case OmniboxPart::LOCATION_BAR_BUBBLE_OUTLINE:
       return OmniboxFieldTrial::IsExperimentalKeywordModeEnabled()
-                 ? TP::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE
-                 : TP::COLOR_OMNIBOX_BUBBLE_OUTLINE;
+                 ? kColorOmniboxBubbleOutlineExperimentalKeywordMode
+                 : kColorOmniboxBubbleOutline;
     case OmniboxPart::RESULTS_BUTTON_BORDER:
-      return TP::COLOR_OMNIBOX_RESULTS_BUTTON_BORDER;
+      return kColorOmniboxResultsButtonBorder;
     case OmniboxPart::RESULTS_BUTTON_INK_DROP:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP_SELECTED
-                      : TP::COLOR_OMNIBOX_RESULTS_BUTTON_INK_DROP;
+      return selected ? kColorOmniboxResultsButtonInkDropSelected
+                      : kColorOmniboxResultsButtonInkDrop;
     default:
       NOTREACHED();
-      return -1;
+      return kColorOmniboxBackground;
   }
 }
 
 }  // namespace
 
-SkColor GetOmniboxColor(const ui::ThemeProvider* theme_provider,
+SkColor GetOmniboxColor(const ui::ColorProvider* color_provider,
                         OmniboxPart part,
                         OmniboxPartState state) {
-  return theme_provider->GetColor(GetThemePropertyId(part, state));
+  return color_provider->GetColor(GetColorId(part, state));
 }
 
 SkColor GetOmniboxSecurityChipColor(
-    const ui::ThemeProvider* theme_provider,
+    const ui::ColorProvider* color_provider,
     security_state::SecurityLevel security_level) {
   if (security_level == security_state::SECURE_WITH_POLICY_INSTALLED_CERT) {
-    return GetOmniboxColor(theme_provider,
+    return GetOmniboxColor(color_provider,
                            OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
   }
 
   if (security_level == security_state::SECURE) {
-    return theme_provider->GetColor(TP::COLOR_OMNIBOX_SECURITY_CHIP_SECURE);
+    return color_provider->GetColor(kColorOmniboxSecurityChipSecure);
   }
   if (security_level == security_state::DANGEROUS)
-    return theme_provider->GetColor(TP::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS);
-  return theme_provider->GetColor(TP::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT);
+    return color_provider->GetColor(kColorOmniboxSecurityChipDangerous);
+  return color_provider->GetColor(kColorOmniboxSecurityChipDefault);
 }
 
 float GetOmniboxStateOpacity(OmniboxPartState state) {
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.h b/chrome/browser/ui/omnibox/omnibox_theme.h
index 8796f83..3b8fa75 100644
--- a/chrome/browser/ui/omnibox/omnibox_theme.h
+++ b/chrome/browser/ui/omnibox/omnibox_theme.h
@@ -9,7 +9,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace ui {
-class ThemeProvider;
+class ColorProvider;
 }
 
 // A part of the omnibox (location bar, location bar decoration, or dropdown).
@@ -42,13 +42,13 @@
 
 // Returns the color for the given |part| and |tint|. An optional |state| can be
 // provided for OmniboxParts that support stateful colors.
-SkColor GetOmniboxColor(const ui::ThemeProvider* theme_provider,
+SkColor GetOmniboxColor(const ui::ColorProvider* color_provider,
                         OmniboxPart part,
                         OmniboxPartState state = OmniboxPartState::NORMAL);
 
 // Returns the color of the security chip given |tint| and |security_level|.
 SkColor GetOmniboxSecurityChipColor(
-    const ui::ThemeProvider* theme_provider,
+    const ui::ColorProvider* color_provider,
     security_state::SecurityLevel security_level);
 
 float GetOmniboxStateOpacity(OmniboxPartState state);
diff --git a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.cc b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.cc
index d68c15a4..0607b8f 100644
--- a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.cc
+++ b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.cc
@@ -80,10 +80,10 @@
 }
 
 void CrostiniAnsibleSoftwareConfigView::OnAnsibleSoftwareConfigurationStarted(
-    const crostini::ContainerId& container_id) {}
+    const guest_os::GuestId& container_id) {}
 
 void CrostiniAnsibleSoftwareConfigView::OnAnsibleSoftwareConfigurationFinished(
-    const crostini::ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool success) {
   DCHECK_EQ(state_, State::CONFIGURING);
 
diff --git a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.h b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.h
index 3c474c88..c91a776 100644
--- a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.h
+++ b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_ANSIBLE_SOFTWARE_CONFIG_VIEW_H_
 
 #include "chrome/browser/ash/crostini/ansible/ansible_management_service.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
@@ -33,9 +34,9 @@
 
   // crostini::AnsibleManagementService::Observer:
   void OnAnsibleSoftwareConfigurationStarted(
-      const crostini::ContainerId& container_id) override;
+      const guest_os::GuestId& container_id) override;
   void OnAnsibleSoftwareConfigurationFinished(
-      const crostini::ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       bool success) override;
 
   std::u16string GetSubtextLabelStringForTesting();
diff --git a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view_browsertest.cc
index 3f3cd5a..2f73cdd6 100644
--- a/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view_browsertest.cc
+++ b/chrome/browser/ui/views/crostini/crostini_ansible_software_config_view_browsertest.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/ash/crostini/ansible/ansible_management_test_helper.h"
 #include "chrome/browser/ash/crostini/crostini_pref_names.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/crostini/crostini_dialogue_browser_test_util.h"
@@ -47,13 +48,12 @@
 
   // crostini::AnsibleManagementService::Observer
   void OnAnsibleSoftwareConfigurationStarted(
-      const crostini::ContainerId& container_id) override {}
+      const guest_os::GuestId& container_id) override {}
   void OnAnsibleSoftwareConfigurationFinished(
-      const crostini::ContainerId& container_id,
+      const guest_os::GuestId& container_id,
       bool success) override {}
 
-  void OnApplyAnsiblePlaybook(
-      const crostini::ContainerId& container_id) override {
+  void OnApplyAnsiblePlaybook(const guest_os::GuestId& container_id) override {
     if (is_apply_ansible_success_) {
       EXPECT_NE(nullptr, ActiveView());
       vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal signal;
@@ -75,7 +75,7 @@
     }
   }
   void OnAnsibleSoftwareInstall(
-      const crostini::ContainerId& container_id) override {
+      const guest_os::GuestId& container_id) override {
     if (is_install_ansible_success_) {
       EXPECT_NE(nullptr, ActiveView());
       EXPECT_TRUE(IsDefaultDialog());
@@ -155,7 +155,7 @@
     is_install_ansible_success_ = success;
   }
 
-  crostini::ContainerId container_id_;
+  guest_os::GuestId container_id_;
 
  private:
   bool HasAcceptButton() { return ActiveView()->GetOkButton() != nullptr; }
diff --git a/chrome/browser/ui/views/crostini/crostini_update_filesystem_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_update_filesystem_view_browsertest.cc
index c15af470..d3ab2de 100644
--- a/chrome/browser/ui/views/crostini/crostini_update_filesystem_view_browsertest.cc
+++ b/chrome/browser/ui/views/crostini/crostini_update_filesystem_view_browsertest.cc
@@ -10,6 +10,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/crostini/crostini_dialogue_browser_test_util.h"
@@ -66,8 +67,8 @@
     EXPECT_EQ(nullptr, ActiveView());
   }
 
-  const crostini::ContainerId kContainerId =
-      crostini::ContainerId("vm_name", "container_name");
+  const guest_os::GuestId kGuestId =
+      guest_os::GuestId("vm_name", "container_name");
 };
 
 // Test the dialog is actually launched.
@@ -109,7 +110,7 @@
   GetFakeCiceroneClient()->set_start_lxd_container_response(reply);
 
   crostini::CrostiniManager::GetForProfile(browser()->profile())
-      ->StartLxdContainer(kContainerId, base::DoNothing());
+      ->StartLxdContainer(kGuestId, base::DoNothing());
   ExpectNoView();
 }
 
@@ -123,7 +124,7 @@
   GetFakeCiceroneClient()->set_start_lxd_container_response(reply);
 
   crostini::CrostiniManager::GetForProfile(browser()->profile())
-      ->StartLxdContainer(kContainerId, base::DoNothing());
+      ->StartLxdContainer(kGuestId, base::DoNothing());
   ExpectView();
 
   ActiveView()->AcceptDialog();
diff --git a/chrome/browser/ui/views/extensions/blocked_action_dialog_view.cc b/chrome/browser/ui/views/extensions/blocked_action_dialog_view.cc
index 3d4d4c88..c310cb1 100644
--- a/chrome/browser/ui/views/extensions/blocked_action_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/blocked_action_dialog_view.cc
@@ -25,37 +25,27 @@
 
 void ShowBlockedActionDialog(Browser* browser,
                              const ExtensionId& extension_id,
-                             bool show_checkbox,
-                             base::OnceCallback<void(bool)> callback) {
-  ShowBlockedActionDialogView(browser, extension_id, show_checkbox,
+                             bool is_updating_permissions,
+                             base::OnceClosure callback) {
+  ShowBlockedActionDialogView(browser, extension_id, is_updating_permissions,
                               std::move(callback));
 }
 
 }  // namespace extensions
 
-namespace {
-
-DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kCheckboxId);
-
-}  // namespace
-
 // static
 void ShowBlockedActionDialogView(Browser* browser,
                                  const extensions::ExtensionId& extension_id,
-                                 bool show_checkbox,
-                                 base::OnceCallback<void(bool)> callback) {
+                                 bool is_updating_permissions,
+                                 base::OnceClosure callback) {
   ExtensionsToolbarContainer* const container =
       GetExtensionsToolbarContainer(browser);
   DCHECK(container);
 
-  auto on_ok_button_clicked = [](ui::DialogModel* dialog_model,
-                                 bool did_show_checkbox,
-                                 base::OnceCallback<void(bool)> callback) {
-    bool checkbox_checked =
-        dialog_model->GetCheckboxByUniqueId(kCheckboxId)->is_checked();
-    std::move(callback).Run(did_show_checkbox && checkbox_checked);
-  };
-
+  // TODO(emiliapaz): Under the new flag, this dialog is also shown when
+  // revoking permissions. Thus, the name `BlockedActionDialog` is not
+  // applicable anymore. Consider renaming this to `ReloadPageBubble` or
+  // something similar.
   ui::DialogModel::Builder dialog_builder;
   if (base::FeatureList::IsEnabled(
           extensions_features::kExtensionsMenuAccessControl)) {
@@ -64,28 +54,22 @@
     content::WebContents* web_contents =
         browser->tab_strip_model()->GetActiveWebContents();
     dialog_builder
-        .SetTitle(l10n_util::GetStringFUTF16(
-            IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE,
-            extension->GetActionName()))
+        .SetTitle(
+            is_updating_permissions
+                ? l10n_util::GetStringUTF16(
+                      IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_UPDATE_PERMISSIONS_TITLE)
+                : l10n_util::GetStringFUTF16(
+                      IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_SINGLE_EXTENSION_TITLE,
+                      extension->GetActionName()))
         .SetIcon(GetIcon(extension, web_contents))
-        .AddBodyText(ui::DialogModelLabel(l10n_util::GetStringUTF16(
-            IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_BODY_TEXT)))
-        .AddOkButton(
-            base::BindOnce(on_ok_button_clicked, dialog_builder.model(),
-                           show_checkbox, std::move(callback)),
-            l10n_util::GetStringUTF16(
-                IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON_LABEL));
-    if (show_checkbox) {
-      dialog_builder.AddCheckbox(
-          kCheckboxId,
-          ui::DialogModelLabel(l10n_util::GetStringUTF16(
-              IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_CHECKBOX_LABEL)));
-    }
+        .AddOkButton(base::BindOnce(std::move(callback)),
+                     l10n_util::GetStringUTF16(
+                         IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON));
   } else {
     dialog_builder
         .SetTitle(l10n_util::GetStringUTF16(
             IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_HEADING))
-        .AddOkButton(base::BindOnce(std::move(callback), /*is_checked=*/false),
+        .AddOkButton(base::BindOnce(std::move(callback)),
                      l10n_util::GetStringUTF16(
                          IDS_EXTENSION_BLOCKED_ACTION_BUBBLE_OK_BUTTON));
   }
diff --git a/chrome/browser/ui/views/extensions/blocked_action_dialog_view.h b/chrome/browser/ui/views/extensions/blocked_action_dialog_view.h
index e69f492..44b54742 100644
--- a/chrome/browser/ui/views/extensions/blocked_action_dialog_view.h
+++ b/chrome/browser/ui/views/extensions/blocked_action_dialog_view.h
@@ -13,7 +13,7 @@
 static void ShowBlockedActionDialogView(
     Browser* browser,
     const extensions::ExtensionId& extension_id,
-    bool show_checkbox,
-    base::OnceCallback<void(bool)> callback);
+    bool is_updating_permissions,
+    base::OnceClosure callback);
 
 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BLOCKED_ACTION_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index bcf1332..e4d95d5c 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -202,8 +202,8 @@
 void InfoBarView::OnPaint(gfx::Canvas* canvas) {
   views::View::OnPaint(canvas);
 
-  const SkColor color = GetThemeProvider()->GetColor(
-      ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR);
+  const SkColor color =
+      GetColorProvider()->GetColor(kColorInfoBarContentAreaSeparator);
   const gfx::RectF local_bounds(GetLocalBounds());
   const gfx::Vector2d separator_offset(0, kSeparatorHeightDip);
   canvas->DrawSharpLine(local_bounds.bottom_left() - separator_offset,
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index ee5a6c831..da6ee33b 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -245,11 +245,12 @@
         label->SetHorizontalAlignment(horizontal_alignment);
         label->SetElideBehavior(gfx::NO_ELIDE);
         label->SetAutoColorReadabilityEnabled(false);
+        const auto* const color_provider = GetColorProvider();
         label->SetBackground(views::CreateSolidBackground(GetOmniboxColor(
-            GetThemeProvider(), OmniboxPart::LOCATION_BAR_BACKGROUND,
+            color_provider, OmniboxPart::LOCATION_BAR_BACKGROUND,
             OmniboxPartState::SELECTED)));
         label->SetEnabledColor(GetOmniboxColor(
-            GetThemeProvider(), OmniboxPart::LOCATION_BAR_TEXT_DEFAULT,
+            color_provider, OmniboxPart::LOCATION_BAR_TEXT_DEFAULT,
             OmniboxPartState::SELECTED));
         label->SetVisible(false);
         return label;
@@ -392,7 +393,7 @@
 
 SkColor LocationBarView::GetColor(OmniboxPart part) const {
   DCHECK(GetWidget());
-  return GetOmniboxColor(GetThemeProvider(), part);
+  return GetOmniboxColor(GetColorProvider(), part);
 }
 
 int LocationBarView::GetBorderRadius() const {
@@ -990,7 +991,7 @@
   } else {
     const SkColor normal = GetColor(OmniboxPart::LOCATION_BAR_BACKGROUND);
     const SkColor hovered = GetOmniboxColor(
-        GetThemeProvider(), OmniboxPart::LOCATION_BAR_BACKGROUND,
+        GetColorProvider(), OmniboxPart::LOCATION_BAR_BACKGROUND,
         OmniboxPartState::HOVERED);
     const double opacity = hover_animation_.GetCurrentValue();
     background_color = gfx::Tween::ColorValueBetween(opacity, normal, hovered);
@@ -1401,7 +1402,7 @@
 
 SkColor LocationBarView::GetSecurityChipColor(
     security_state::SecurityLevel security_level) const {
-  return GetOmniboxSecurityChipColor(GetThemeProvider(), security_level);
+  return GetOmniboxSecurityChipColor(GetColorProvider(), security_level);
 }
 
 bool LocationBarView::ShowPageInfoDialog() {
diff --git a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
index d07da117..20f90602 100644
--- a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
+++ b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
@@ -149,12 +149,8 @@
 }
 
 SkColor OmniboxChipButton::GetTextAndIconColor() const {
-  if (theme_ == OmniboxChipTheme::kIconStyle) {
-    // Use ThemeProvider rather than ColorProvider to correctly match the color
-    // used for page action icons.
-    return GetThemeProvider()->GetColor(
-        ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON);
-  }
+  if (theme_ == OmniboxChipTheme::kIconStyle)
+    return GetColorProvider()->GetColor(kColorOmniboxResultsIcon);
 
   return GetColorProvider()->GetColor(
       theme_ == OmniboxChipTheme::kLowVisibility
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index a5405c94..81a62db 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -12,7 +12,7 @@
 #include "base/feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_row_view.h"
@@ -180,9 +180,8 @@
             base::Unretained(this)));
   }
 
-  views::SetCascadingThemeProviderColor(
-      this, views::kCascadingBackgroundColor,
-      ThemeProperties::COLOR_OMNIBOX_RESULTS_BG);
+  views::SetCascadingColorProviderColor(this, views::kCascadingBackgroundColor,
+                                        kColorOmniboxResultsBackground);
 }
 
 OmniboxPopupContentsView::~OmniboxPopupContentsView() {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
index 752b887..6fe7a56 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view_browsertest.cc
@@ -189,13 +189,13 @@
 
   SkColor GetSelectedColor(Browser* browser) {
     return GetOmniboxColor(
-        BrowserView::GetBrowserViewForBrowser(browser)->GetThemeProvider(),
+        BrowserView::GetBrowserViewForBrowser(browser)->GetColorProvider(),
         OmniboxPart::RESULTS_BACKGROUND, OmniboxPartState::SELECTED);
   }
 
   SkColor GetNormalColor(Browser* browser) {
     return GetOmniboxColor(
-        BrowserView::GetBrowserViewForBrowser(browser)->GetThemeProvider(),
+        BrowserView::GetBrowserViewForBrowser(browser)->GetColorProvider(),
         OmniboxPart::RESULTS_BACKGROUND);
   }
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 443437c..34a5044 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -241,11 +241,11 @@
     return nullptr;
 
   return views::CreateSolidBackground(GetOmniboxColor(
-      view->GetThemeProvider(), OmniboxPart::RESULTS_BACKGROUND, part_state));
+      view->GetColorProvider(), OmniboxPart::RESULTS_BACKGROUND, part_state));
 }
 
 SkColor OmniboxResultView::GetColor(OmniboxPart part) const {
-  return GetOmniboxColor(GetThemeProvider(), part, GetThemeState());
+  return GetOmniboxColor(GetColorProvider(), part, GetThemeState());
 }
 
 void OmniboxResultView::SetMatch(const AutocompleteMatch& match) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
index 9d3e7d6..b89b126 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
@@ -155,10 +155,10 @@
     }
 
     SkColor text_color = GetOmniboxColor(
-        GetThemeProvider(), OmniboxPart::RESULTS_TEXT_DIMMED, part_state);
+        GetColorProvider(), OmniboxPart::RESULTS_TEXT_DIMMED, part_state);
     header_label_->SetEnabledColor(text_color);
 
-    SkColor icon_color = GetOmniboxColor(GetThemeProvider(),
+    SkColor icon_color = GetOmniboxColor(GetColorProvider(),
                                          OmniboxPart::RESULTS_ICON, part_state);
     views::InkDrop::Get(header_toggle_button_)->SetBaseColor(icon_color);
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
index 84b608e..d828cde0 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
@@ -64,7 +64,7 @@
         GetOmniboxStateOpacity(OmniboxPartState::HOVERED));
     views::InkDrop::Get(this)->SetBaseColorCallback(base::BindRepeating(
         [](OmniboxSuggestionRowButton* host) {
-          return GetOmniboxColor(host->GetThemeProvider(),
+          return GetOmniboxColor(host->GetColorProvider(),
                                  OmniboxPart::RESULTS_BUTTON_INK_DROP,
                                  host->theme_state_);
         },
@@ -99,23 +99,23 @@
     MdTextButton::OnThemeChanged();
     // We can't use colors from NativeTheme as the omnibox theme might be
     // different (for example, if the NTP colors are customized).
-    const auto* const theme_provider = GetThemeProvider();
+    const auto* const color_provider = GetColorProvider();
     SkColor icon_color = GetOmniboxColor(
-        theme_provider, OmniboxPart::RESULTS_ICON, theme_state_);
+        color_provider, OmniboxPart::RESULTS_ICON, theme_state_);
     SetImage(
         views::Button::STATE_NORMAL,
         gfx::CreateVectorIcon(*icon_, GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
                               icon_color));
     SetEnabledTextColors(GetOmniboxColor(
-        theme_provider, OmniboxPart::RESULTS_TEXT_DEFAULT, theme_state_));
+        color_provider, OmniboxPart::RESULTS_TEXT_DEFAULT, theme_state_));
   }
 
   void UpdateBackgroundColor() override {
-    const auto* const theme_provider = GetThemeProvider();
+    const auto* const color_provider = GetColorProvider();
     SkColor stroke_color = GetOmniboxColor(
-        theme_provider, OmniboxPart::RESULTS_BUTTON_BORDER, theme_state_);
+        color_provider, OmniboxPart::RESULTS_BUTTON_BORDER, theme_state_);
     SkColor fill_color = GetOmniboxColor(
-        theme_provider, OmniboxPart::RESULTS_BACKGROUND, theme_state_);
+        color_provider, OmniboxPart::RESULTS_BACKGROUND, theme_state_);
     SetBackground(CreateBackgroundFromPainter(
         views::Painter::CreateRoundRectWith1PxBorderPainter(
             fill_color, stroke_color, GetCornerRadius())));
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index ff8fe58c..e425067 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -592,7 +592,7 @@
   views::Textfield::OnThemeChanged();
 
   const SkColor dimmed_text_color = GetOmniboxColor(
-      GetThemeProvider(), OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
+      GetColorProvider(), OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
   set_placeholder_text_color(dimmed_text_color);
 
   EmphasizeURLComponents();
@@ -990,7 +990,7 @@
 
 void OmniboxViewViews::SetEmphasis(bool emphasize, const gfx::Range& range) {
   SkColor color = GetOmniboxColor(
-      GetThemeProvider(), emphasize ? OmniboxPart::LOCATION_BAR_TEXT_DEFAULT
+      GetColorProvider(), emphasize ? OmniboxPart::LOCATION_BAR_TEXT_DEFAULT
                                     : OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
   if (range.IsValid())
     ApplyColor(color, range);
diff --git a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
index 4e242f4..52c1040 100644
--- a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
+++ b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
@@ -82,7 +82,7 @@
   void OnThemeChanged() override {
     views::View::OnThemeChanged();
     const SkColor background_color =
-        GetOmniboxColor(GetThemeProvider(), OmniboxPart::RESULTS_BACKGROUND);
+        GetOmniboxColor(GetColorProvider(), OmniboxPart::RESULTS_BACKGROUND);
     SetBackground(views::CreateSolidBackground(background_color));
   }
 };
@@ -101,7 +101,7 @@
   void OnThemeChanged() override {
     views::View::OnThemeChanged();
     const SkColor background_color =
-        GetOmniboxColor(GetThemeProvider(), OmniboxPart::RESULTS_BACKGROUND);
+        GetOmniboxColor(GetColorProvider(), OmniboxPart::RESULTS_BACKGROUND);
 
     // Paint a stroke of the background color as a 1 px border to hide the
     // underlying antialiased location bar/toolbar edge.  The round rect here is
diff --git a/chrome/browser/ui/views/side_panel/side_panel.cc b/chrome/browser/ui/views/side_panel/side_panel.cc
index 8088cb6..949cead4 100644
--- a/chrome/browser/ui/views/side_panel/side_panel.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel.cc
@@ -8,12 +8,11 @@
 
 #include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
-#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/top_container_background.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/theme_provider.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
@@ -98,8 +97,8 @@
 
     cc::PaintFlags flags;
     flags.setStrokeWidth(stroke_thickness);
-    flags.setColor(view.GetThemeProvider()->GetColor(
-        ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR));
+    flags.setColor(
+        view.GetColorProvider()->GetColor(kColorSidePanelContentAreaSeparator));
     flags.setStyle(cc::PaintFlags::kStroke_Style);
     flags.setAntiAlias(true);
 
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc
index 1a95024..8c3a7cba 100644
--- a/chrome/browser/ui/views/status_bubble_views.cc
+++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -20,14 +20,13 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "cc/paint/paint_flags.h"
-#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/color/chrome_color_id.h"
 #include "components/url_formatter/elide_url.h"
 #include "components/url_formatter/url_formatter.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/pathops/SkPathOps.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/theme_provider.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/animation/linear_animation.h"
@@ -427,17 +426,17 @@
 }
 
 void StatusView::SetTextLabelColors(views::Label* text) {
-  const auto* theme_provider = status_bubble_->base_view()->GetThemeProvider();
+  const auto* color_provider = status_bubble_->base_view()->GetColorProvider();
   const bool active =
       status_bubble_->base_view()->GetWidget()->ShouldPaintAsActive();
-  SkColor bubble_color = theme_provider->GetColor(
-      active ? ThemeProperties::COLOR_STATUS_BUBBLE_ACTIVE
-             : ThemeProperties::COLOR_STATUS_BUBBLE_INACTIVE);
+  SkColor bubble_color = color_provider->GetColor(
+      active ? kColorStatusBubbleBackgroundFrameActive
+             : kColorStatusBubbleBackgroundFrameInactive);
   text->SetBackgroundColor(bubble_color);
   // Text color is the background tab text color, adjusted if required.
-  text->SetEnabledColor(theme_provider->GetColor(
-      active ? ThemeProperties::COLOR_STATUS_BUBBLE_TEXT_ACTIVE
-             : ThemeProperties::COLOR_STATUS_BUBBLE_TEXT_INACTIVE));
+  text->SetEnabledColor(color_provider->GetColor(
+      active ? kColorStatusBubbleForegroundFrameActive
+             : kColorStatusBubbleForegroundFrameInactive));
 }
 
 void StatusView::OnPaint(gfx::Canvas* canvas) {
@@ -539,16 +538,15 @@
   Op(path, stroke_path, kDifference_SkPathOp, &fill_path);
   flags.setStyle(cc::PaintFlags::kFill_Style);
 
-  const auto* theme_provider = status_bubble_->base_view()->GetThemeProvider();
+  const auto* color_provider = status_bubble_->base_view()->GetColorProvider();
   const auto id =
       status_bubble_->base_view()->GetWidget()->ShouldPaintAsActive()
-          ? ThemeProperties::COLOR_STATUS_BUBBLE_ACTIVE
-          : ThemeProperties::COLOR_STATUS_BUBBLE_INACTIVE;
-  flags.setColor(theme_provider->GetColor(id));
+          ? kColorStatusBubbleBackgroundFrameActive
+          : kColorStatusBubbleBackgroundFrameInactive;
+  flags.setColor(color_provider->GetColor(id));
   canvas->sk_canvas()->drawPath(fill_path, flags);
 
-  flags.setColor(
-      theme_provider->GetColor(ThemeProperties::COLOR_STATUS_BUBBLE_SHADOW));
+  flags.setColor(color_provider->GetColor(kColorStatusBubbleShadow));
   canvas->sk_canvas()->drawPath(stroke_path, flags);
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
index 4c9bcb9..ff92f750 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -20,7 +20,7 @@
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
 #include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/tabs/tab_renderer_data.h"
 #include "chrome/browser/ui/tabs/tab_style.h"
 #include "chrome/browser/ui/thumbnails/thumbnail_image.h"
@@ -36,7 +36,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/theme_provider.h"
 #include "ui/color/color_id.h"
 #include "ui/color/color_provider.h"
 #include "ui/compositor/layer.h"
@@ -562,19 +561,19 @@
     if (image_type_ == ImageType::kPlaceholder)
       return;
 
-    // Theme provider may be null if there is no associated widget. In that case
-    // there is nothing to render, and we can't get theme default colors to
-    // render with anyway, so bail out.
-    const ui::ThemeProvider* const theme_provider = GetThemeProvider();
-    if (!theme_provider)
+    // Color provider may be null if there is no associated widget. In that case
+    // there is nothing to render, and we can't get default colors to render
+    // with anyway, so bail out.
+    const auto* const color_provider = GetColorProvider();
+    if (!color_provider)
       return;
 
     StartFadeOut();
 
     // Check the no-preview color and size to see if it needs to be
     // regenerated. DPI or theme change can cause a regeneration.
-    const SkColor foreground_color = theme_provider->GetColor(
-        ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_FOREGROUND);
+    const SkColor foreground_color =
+        color_provider->GetColor(kColorTabHoverCardForeground);
 
     // Set the no-preview placeholder image. All sizes are in DIPs.
     // gfx::CreateVectorIcon() caches its result so there's no need to store
@@ -629,8 +628,8 @@
         image_view->SetVerticalAlignment(views::ImageView::Alignment::kCenter);
         image_view->SetImageSize(image.size());
         image_view->SetBackground(views::CreateSolidBackground(
-            image_view->GetThemeProvider()->GetColor(
-                ThemeProperties::COLOR_HOVER_CARD_NO_PREVIEW_BACKGROUND)));
+            image_view->GetColorProvider()->GetColor(
+                kColorTabHoverCardBackground)));
         break;
       case ImageType::kThumbnail:
         image_view->SetVerticalAlignment(views::ImageView::Alignment::kLeading);
@@ -673,10 +672,10 @@
   void StartFadeOut() {
     // If we aren't visible, don't have a widget, or our widget is being
     // destructed and has no theme provider, skip trying to fade out since a
-    // ThemeProvider is needed for fading out placeholder images. (Note that
-    // GetThemeProvider() returns nullptr if there is no widget.)
+    // ColorProvider is needed for fading out placeholder images. (Note that
+    // GetColorProvider() returns nullptr if there is no widget.)
     // See: crbug.com/1246914
-    if (!GetVisible() || !GetThemeProvider())
+    if (!GetVisible() || !GetColorProvider())
       return;
 
     if (!GetPreviewImageCrossfadeStart().has_value())
@@ -846,7 +845,7 @@
   // existing thumbnail to be decompressed.
   //
   // Note that this code has to go after CreateBubble() above, since setting up
-  // the placeholder image and background color require a ThemeProvider, which
+  // the placeholder image and background color require a ColorProvider, which
   // is only available once this View has been added to its widget.
   if (thumbnail_view_ && !tab->data().thumbnail->has_data() &&
       !tab->IsActive()) {
diff --git a/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler.cc b/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler.cc
index 7943c11..7be0d6b 100644
--- a/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler.cc
+++ b/chrome/browser/ui/webui/access_code_cast/access_code_cast_handler.cc
@@ -167,10 +167,10 @@
     return;
   }
   AddSinkCallback callback_with_default_invoker =
-      mojo::WrapCallbackWithDefaultInvokeIfNotRun(
-          std::move(callback), AddSinkResultCode::UNKNOWN_ERROR);
+      mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback),
+          AddSinkResultCode::UNKNOWN_ERROR);
   add_sink_callback_ = std::move(base::BindOnce(&AddSinkMetricsCallback))
-                           .Then(std::move(callback_with_default_invoker));
+          .Then(std::move(callback_with_default_invoker));
   access_code_sink_service_->DiscoverSink(
       access_code, base::BindOnce(&AccessCodeCastHandler::OnSinkAddedResult,
                                   weak_ptr_factory_.GetWeakPtr()));
@@ -199,6 +199,11 @@
     return;
   }
 
+  // Sink has been completely added so caller can be alerted.
+  if (base::FeatureList::IsEnabled(features::kAccessCodeCastRememberDevices)) {
+    access_code_sink_service_->StoreSinkAndSetExpirationTimer(sink_id_.value());
+  }
+
   std::move(add_sink_callback_).Run(AddSinkResultCode::OK);
 }
 
@@ -218,12 +223,6 @@
   }
   if (sink_id) {
     sink_id_ = sink_id;
-    // Sink has been completely added so caller can be alerted.
-    if (base::FeatureList::IsEnabled(
-            features::kAccessCodeCastRememberDevices)) {
-      access_code_sink_service_->StoreSinkAndSetExpirationTimer(
-          sink_id_.value());
-    }
   }
   CheckForDiscoveryCompletion();
 }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
index e4c7085c..38d1c2f 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -267,46 +267,47 @@
 
   auto search_box = realbox::mojom::SearchBoxTheme::New();
   search_box->bg =
-      GetOmniboxColor(theme_provider, OmniboxPart::LOCATION_BAR_BACKGROUND);
+      GetOmniboxColor(&color_provider, OmniboxPart::LOCATION_BAR_BACKGROUND);
   search_box->bg_hovered =
-      GetOmniboxColor(theme_provider, OmniboxPart::LOCATION_BAR_BACKGROUND,
+      GetOmniboxColor(&color_provider, OmniboxPart::LOCATION_BAR_BACKGROUND,
                       OmniboxPartState::HOVERED);
   search_box->border_color =
       webui::GetNativeTheme(web_contents)->UserHasContrastPreference()
           ? color_provider.GetColor(kColorLocationBarBorder)
           : SkColorSetRGB(218, 220, 224);  // google-grey-300
-  search_box->icon = GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_ICON);
+  search_box->icon =
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_ICON);
   search_box->icon_selected = GetOmniboxColor(
-      theme_provider, OmniboxPart::RESULTS_ICON, OmniboxPartState::SELECTED);
+      &color_provider, OmniboxPart::RESULTS_ICON, OmniboxPartState::SELECTED);
   search_box->is_dark = !color_utils::IsDark(text_color);
   search_box->ntp_bg = color_provider.GetColor(kColorNewTabPageBackground);
   search_box->placeholder =
-      GetOmniboxColor(theme_provider, OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
+      GetOmniboxColor(&color_provider, OmniboxPart::LOCATION_BAR_TEXT_DIMMED);
   search_box->results_bg =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_BACKGROUND);
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_BACKGROUND);
   search_box->results_bg_hovered =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_BACKGROUND,
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_BACKGROUND,
                       OmniboxPartState::HOVERED);
   search_box->results_bg_selected =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_BACKGROUND,
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_BACKGROUND,
                       OmniboxPartState::SELECTED);
   search_box->results_dim =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_DIMMED);
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_DIMMED);
   search_box->results_dim_selected =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_DIMMED,
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_DIMMED,
                       OmniboxPartState::SELECTED);
   search_box->results_text =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_DEFAULT);
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_DEFAULT);
   search_box->results_text_selected =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_DEFAULT,
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_DEFAULT,
                       OmniboxPartState::SELECTED);
   search_box->results_url =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_URL);
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_URL);
   search_box->results_url_selected =
-      GetOmniboxColor(theme_provider, OmniboxPart::RESULTS_TEXT_URL,
+      GetOmniboxColor(&color_provider, OmniboxPart::RESULTS_TEXT_URL,
                       OmniboxPartState::SELECTED);
   search_box->text =
-      GetOmniboxColor(theme_provider, OmniboxPart::LOCATION_BAR_TEXT_DEFAULT);
+      GetOmniboxColor(&color_provider, OmniboxPart::LOCATION_BAR_TEXT_DEFAULT);
   theme->search_box = std::move(search_box);
 
   return theme;
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
index 61f1fa5..5d09602 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler_unittest.cc
@@ -299,44 +299,32 @@
       .WillByDefault(testing::Return(true));
   mock_color_provider_source_.SetColor(
       kColorNewTabPageMostVisitedTileBackground, SkColorSetRGB(0, 0, 4));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_BACKGROUND))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 5)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 6)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON_SELECTED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 7)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 8)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_BG))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 9)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_HOVERED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 10)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_SELECTED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 11)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 12)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 13)));
-  ON_CALL(mock_theme_provider_, GetColor(ThemeProperties::COLOR_OMNIBOX_TEXT))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 14)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 15)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_URL))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 16)));
-  ON_CALL(mock_theme_provider_,
-          GetColor(ThemeProperties::COLOR_OMNIBOX_RESULTS_URL_SELECTED))
-      .WillByDefault(testing::Return(SkColorSetRGB(0, 0, 17)));
+  mock_color_provider_source_.SetColor(kColorOmniboxBackground,
+                                       SkColorSetRGB(0, 0, 5));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsIcon,
+                                       SkColorSetRGB(0, 0, 6));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsIconSelected,
+                                       SkColorSetRGB(0, 0, 7));
+  mock_color_provider_source_.SetColor(kColorOmniboxTextDimmed,
+                                       SkColorSetRGB(0, 0, 8));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsBackground,
+                                       SkColorSetRGB(0, 0, 9));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsBackgroundHovered,
+                                       SkColorSetRGB(0, 0, 10));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsBackgroundSelected,
+                                       SkColorSetRGB(0, 0, 11));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsTextDimmed,
+                                       SkColorSetRGB(0, 0, 12));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsTextDimmedSelected,
+                                       SkColorSetRGB(0, 0, 13));
+  mock_color_provider_source_.SetColor(kColorOmniboxText,
+                                       SkColorSetRGB(0, 0, 14));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsTextSelected,
+                                       SkColorSetRGB(0, 0, 15));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsUrl,
+                                       SkColorSetRGB(0, 0, 16));
+  mock_color_provider_source_.SetColor(kColorOmniboxResultsUrlSelected,
+                                       SkColorSetRGB(0, 0, 17));
 
   theme_service_observer_->OnThemeChanged();
   mock_page_.FlushForTesting();
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
index 2ddb1202..b0673c1 100644
--- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -316,6 +316,8 @@
       {"bluetoothManaged", IDS_SETTINGS_BLUETOOTH_MANAGED},
       {"enableFastPairLabel", IDS_BLUETOOTH_ENABLE_FAST_PAIR_LABEL},
       {"enableFastPairSubtitle", IDS_BLUETOOTH_ENABLE_FAST_PAIR_SUBTITLE},
+      {"savedDevicesLabel", IDS_BLUETOOTH_SAVED_DEVICES_LABEL},
+      {"savedDevicesSubtitle", IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE},
       {"bluetoothPrimaryUserControlled",
        IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED},
       {"bluetoothDeviceWithConnectionStatus",
@@ -360,6 +362,8 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
   html_source->AddBoolean("enableFastPairFlag", features::IsFastPairEnabled());
+  html_source->AddBoolean("enableSavedDevicesFlag",
+                          features::IsFastPairSavedDevicesEnabled());
   chromeos::bluetooth::AddLoadTimeData(html_source);
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
index dbe5e52..5e1a6d7 100644
--- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -270,7 +270,7 @@
 void CrostiniHandler::HandleExportCrostiniContainer(
     const base::Value::List& args) {
   CHECK_EQ(1U, args.size());
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   VLOG(1) << "Exporting  = " << container_id;
 
   crostini::CrostiniExportImport::GetForProfile(profile_)->ExportContainer(
@@ -280,7 +280,7 @@
 void CrostiniHandler::HandleImportCrostiniContainer(
     const base::Value::List& args) {
   CHECK_EQ(1U, args.size());
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   VLOG(1) << "Importing  = " << container_id;
   crostini::CrostiniExportImport::GetForProfile(profile_)->ImportContainer(
       container_id, web_ui()->GetWebContents());
@@ -332,7 +332,7 @@
 }
 
 void CrostiniHandler::OnContainerOsReleaseChanged(
-    const crostini::ContainerId& container_id,
+    const guest_os::GuestId& container_id,
     bool can_upgrade) {
   if (crostini::CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(
           profile_) &&
@@ -488,7 +488,7 @@
   CHECK_EQ(5U, args.size());
 
   std::string callback_id = args[0].GetString();
-  crostini::ContainerId container_id(args[1]);
+  guest_os::GuestId container_id(args[1]);
   int port_number = args[2].GetInt();
   int protocol_type = args[3].GetInt();
   std::string label = args[4].GetString();
@@ -513,7 +513,7 @@
   CHECK_EQ(4U, list.size());
 
   std::string callback_id = list[0].GetString();
-  crostini::ContainerId container_id(list[1]);
+  guest_os::GuestId container_id(list[1]);
   int port_number = list[2].GetInt();
   int protocol_type = list[3].GetInt();
 
@@ -539,7 +539,7 @@
   }
 
   crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemoveAllPorts(
-      crostini::ContainerId(args[0]));
+      guest_os::GuestId(args[0]));
 }
 
 void CrostiniHandler::HandleActivateCrostiniPortForward(
@@ -548,7 +548,7 @@
   CHECK_EQ(4U, list.size());
 
   std::string callback_id = list[0].GetString();
-  crostini::ContainerId container_id(list[1]);
+  guest_os::GuestId container_id(list[1]);
   int port_number = list[2].GetInt();
   int protocol_type = list[3].GetInt();
 
@@ -571,7 +571,7 @@
   CHECK_EQ(4U, list.size());
 
   std::string callback_id = list[0].GetString();
-  crostini::ContainerId container_id(list[1]);
+  guest_os::GuestId container_id(list[1]);
   int port_number = list[2].GetInt();
   int protocol_type = list[3].GetInt();
 
@@ -657,13 +657,13 @@
 }
 
 void CrostiniHandler::OnContainerStarted(
-    const crostini::ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   FireWebUIListener("crostini-status-changed", base::Value(true));
   HandleRequestContainerInfo(base::Value::List());
 }
 
 void CrostiniHandler::OnContainerShutdown(
-    const crostini::ContainerId& container_id) {
+    const guest_os::GuestId& container_id) {
   FireWebUIListener("crostini-status-changed", base::Value(false));
   HandleRequestContainerInfo(base::Value::List());
 }
@@ -679,7 +679,7 @@
 
 void CrostiniHandler::HandleCreateContainer(const base::Value::List& args) {
   CHECK_EQ(4U, args.size());
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   GURL image_server_url(args[1].GetString());
   std::string image_alias(args[2].GetString());
   base::FilePath ansible_playbook(args[3].GetString());
@@ -727,7 +727,7 @@
     return;
   }
 
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   if (container_id == crostini::DefaultContainerId()) {
     LOG(ERROR) << "Deleting " << container_id << " not permitted";
     return;
@@ -741,8 +741,7 @@
       container_id, std::move(options),
       base::BindOnce(
           [](base::WeakPtr<crostini::CrostiniManager> crostini_manager,
-             crostini::ContainerId container_id,
-             crostini::CrostiniResult result) {
+             guest_os::GuestId container_id, crostini::CrostiniResult result) {
             if (crostini_manager &&
                 result == crostini::CrostiniResult::SUCCESS) {
               crostini_manager->DeleteLxdContainer(container_id,
@@ -765,7 +764,7 @@
           ->GetList();
 
   for (const auto& dict : containers) {
-    crostini::ContainerId container_id(dict);
+    guest_os::GuestId container_id(dict);
     base::Value::Dict container_info_value;
     container_info_value.Set(kIdKey, container_id.ToDictValue());
     auto info =
@@ -793,7 +792,7 @@
     const base::Value::List& args) {
   CHECK_EQ(2U, args.size());
 
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   SkColor badge_color(args[1].FindDoubleKey("value").value());
 
   crostini::SetContainerBadgeColor(profile_, container_id, badge_color);
@@ -806,7 +805,7 @@
     return;
   }
 
-  crostini::ContainerId container_id(args[0]);
+  guest_os::GuestId container_id(args[0]);
   if (crostini::ShouldStopVm(profile_, container_id)) {
     crostini::CrostiniManager::GetForProfile(profile_)->StopVm(
         container_id.vm_name, base::DoNothing());
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
index 83b9778..412f1d6 100644
--- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/ash/crostini/crostini_export_import.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_port_forwarder.h"
+#include "chrome/browser/ash/guest_os/guest_id.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
@@ -60,7 +61,7 @@
   void OnCrostiniDialogStatusChanged(crostini::DialogType dialog_type,
                                      bool open) override;
   // crostini::CrostiniContainerPropertiesObserver
-  void OnContainerOsReleaseChanged(const crostini::ContainerId& container_id,
+  void OnContainerOsReleaseChanged(const guest_os::GuestId& container_id,
                                    bool can_upgrade) override;
   // Handle a request for the CrostiniExportImport operation status.
   void HandleCrostiniExportImportOperationStatusRequest(
@@ -121,9 +122,9 @@
   // Checks if Crostini is running.
   void HandleCheckCrostiniIsRunning(const base::Value::List& args);
   // crostini::ContainerStartedObserver
-  void OnContainerStarted(const crostini::ContainerId& container_id) override;
+  void OnContainerStarted(const guest_os::GuestId& container_id) override;
   // crostini::ContainerShutdownObserver
-  void OnContainerShutdown(const crostini::ContainerId& container_id) override;
+  void OnContainerShutdown(const guest_os::GuestId& container_id) override;
   // Handles a request to shut down Crostini.
   void HandleShutdownCrostini(const base::Value::List& args);
   // Handle a request for checking permission for changing ARC adb sideloading.
diff --git a/chrome/browser/ui/webui/settings/chromeos/main_section.cc b/chrome/browser/ui/webui/settings/chromeos/main_section.cc
index 91d3ce8..ccf3c46 100644
--- a/chrome/browser/ui/webui/settings/chromeos/main_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/main_section.cc
@@ -254,6 +254,10 @@
       "secondaryUserBannerText",
       l10n_util::GetStringFUTF16(IDS_SETTINGS_SECONDARY_USER_BANNER,
                                  base::ASCIIToUTF16(primary_user_email)));
+  html_source->AddString(
+      "sublableWithEmail",
+      l10n_util::GetStringFUTF16(IDS_BLUETOOTH_SAVED_DEVICES_SUBTITLE,
+                                 base::ASCIIToUTF16(primary_user_email)));
 }
 
 std::unique_ptr<PluralStringHandler> MainSection::CreatePluralStringHandler() {
diff --git a/chrome/browser/usb/android/BUILD.gn b/chrome/browser/usb/android/BUILD.gn
index 703d81a..251164c 100644
--- a/chrome/browser/usb/android/BUILD.gn
+++ b/chrome/browser/usb/android/BUILD.gn
@@ -42,8 +42,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   sources = [
     "junit/src/org/chromium/chrome/browser/usb/UsbNotificationManagerTest.java",
   ]
@@ -56,7 +54,6 @@
     "//chrome/test/android:chrome_java_unit_test_support",
     "//components/browser_ui/notifications/android:test_support_java",
     "//components/url_formatter/android:url_formatter_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit:junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
diff --git a/chrome/browser/util/BUILD.gn b/chrome/browser/util/BUILD.gn
index d860049..93a78daa 100644
--- a/chrome/browser/util/BUILD.gn
+++ b/chrome/browser/util/BUILD.gn
@@ -37,7 +37,6 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
   sources = [
     "android/java/src/org/chromium/chrome/browser/util/ChromeFileProviderTest.java",
     "android/java/src/org/chromium/chrome/browser/util/HashUtilTest.java",
@@ -50,7 +49,6 @@
     "//base/test:test_support_java",
     "//chrome/test/android:chrome_java_unit_test_support",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/chrome/browser/video_tutorials/internal/BUILD.gn b/chrome/browser/video_tutorials/internal/BUILD.gn
index 7064c077..461e44b73 100644
--- a/chrome/browser/video_tutorials/internal/BUILD.gn
+++ b/chrome/browser/video_tutorials/internal/BUILD.gn
@@ -145,7 +145,6 @@
   }
 
   robolectric_library("junit") {
-    testonly = true
     sources = [
       "android/java/src/org/chromium/chrome/browser/video_tutorials/PlaybackStateObserverUnitTest.java",
       "android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java",
@@ -161,7 +160,6 @@
       "//chrome/browser/video_tutorials:test_support_java",
       "//content/public/android:content_java",
       "//services/media_session/public/cpp/android:media_session_java",
-      "//third_party/android_deps:robolectric_all_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/junit",
       "//third_party/mockito:mockito_java",
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 30a9473..821f8768 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1655315802-81d864008e6376e5b47455e1b42857e9b316eb80.profdata
+chrome-linux-main-1655337558-3b7d3637bfebf32674e4f001270d7bc857e28a19.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 5678c30..c4c2d19 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1655315802-fa5ce9679a0b26173e4bb435e646fb867684eb4a.profdata
+chrome-mac-main-1655337558-32f34df87c835ede0dc4b1ae6b3e035e8de0e0e9.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 3a2226eb..21e2579 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1655315802-ea1cdc796e9bd324873db95d23f31e04f5ae5db1.profdata
+chrome-win32-main-1655337558-1ada0e53f07ce62ba7cc2a9bbecfd62d15d846d1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 7480933..b0335b2 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1655305046-49e31d8168e3841e34a4495d3f79e78d5a3b9592.profdata
+chrome-win64-main-1655326797-f816252b17fe520d72e5991ba042ce2c9ad00fcd.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index b1d333d..ebc4aae 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -53,7 +53,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 const base::Feature kAppDiscoveryForOobe{"AppDiscoveryForOobe",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
+                                         base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/test/base/test_chrome_web_ui_controller_factory.cc b/chrome/test/base/test_chrome_web_ui_controller_factory.cc
index 2c72f8a..0827243e 100644
--- a/chrome/test/base/test_chrome_web_ui_controller_factory.cc
+++ b/chrome/test/base/test_chrome_web_ui_controller_factory.cc
@@ -71,6 +71,8 @@
                               std::make_unique<TestDataSource>("webui"));
 
   content::WebUIDataSource* source = webui::CreateWebUITestDataSource();
+  if (provider)
+    provider->DataSourceOverrides(source);
   content::WebUIDataSource::Add(profile, source);
 
   return controller;
diff --git a/chrome/test/base/test_chrome_web_ui_controller_factory.h b/chrome/test/base/test_chrome_web_ui_controller_factory.h
index f5b6ab9..25b654458 100644
--- a/chrome/test/base/test_chrome_web_ui_controller_factory.h
+++ b/chrome/test/base/test_chrome_web_ui_controller_factory.h
@@ -11,6 +11,7 @@
 
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
 
 // A test implementation of ChromeWebUIControllerFactory that provides a
 // registry to override CreateWebUIControllerForURL() by host.
@@ -25,6 +26,10 @@
         content::WebUI* web_ui,
         const GURL& url) = 0;
 
+    // Override this method to customize `source` for the newly created WebUI
+    // controller.
+    virtual void DataSourceOverrides(content::WebUIDataSource* source) {}
+
    protected:
     virtual ~WebUIProvider();
   };
diff --git a/chrome/test/chromedriver/key_converter.cc b/chrome/test/chromedriver/key_converter.cc
index 46c3fed..76c1c2da 100644
--- a/chrome/test/chromedriver/key_converter.cc
+++ b/chrome/test/chromedriver/key_converter.cc
@@ -622,7 +622,7 @@
   if (!action_object->GetString("value", &raw_key))
     return Status(kUnknownError, "missing 'value'");
 
-  size_t char_index = 0;
+  int32_t char_index = 0;
   base_icu::UChar32 code_point;
   base::ReadUnicodeCharacter(raw_key.c_str(), raw_key.size(), &char_index,
                              &code_point);
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 34f0475..87d1551 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -1400,11 +1400,12 @@
         bool valid = action_item->GetString("value", &key);
         if (valid) {
           // check if key is a single unicode code point
-          size_t char_index = 0;
+          int32_t char_index = 0;
           base_icu::UChar32 code_point;
-          valid = base::ReadUnicodeCharacter(key.c_str(), key.size(),
-                                             &char_index, &code_point) &&
-                  char_index + 1 == key.size();
+          valid =
+              base::ReadUnicodeCharacter(key.c_str(), key.size(), &char_index,
+                                         &code_point) &&
+              static_cast<std::string::size_type>(char_index + 1) == key.size();
         }
         if (!valid)
           return Status(kInvalidArgument,
diff --git a/chrome/test/data/fenced_frames/report1.html b/chrome/test/data/fenced_frames/report1.html
new file mode 100644
index 0000000..2526072
--- /dev/null
+++ b/chrome/test/data/fenced_frames/report1.html
@@ -0,0 +1,4 @@
+<html>
+<head></head>
+<body>This page has no title.</body>
+</html>
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index 9f9f968..466d0147 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -504,9 +504,16 @@
   }
 
   if (is_chromeos_ash) {
-    deps += [ "chromeos/personalization_app:build_grdp" ]
-    grdp_files +=
-        [ "$target_gen_dir/chromeos/personalization_app/resources.grdp" ]
+    deps += [
+      "chromeos/personalization_app:build_grdp",
+      "//ui/file_manager:build_tests_gen_grdp",
+      "//ui/file_manager:build_tests_grdp",
+    ]
+    grdp_files += [
+      "$target_gen_dir/chromeos/personalization_app/resources.grdp",
+      "$root_gen_dir/ui/file_manager/tests_resources.grdp",
+      "$root_gen_dir/ui/file_manager/tests_gen_resources.grdp",
+    ]
   }
 
   manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
index 78b16b5..b88e9a5 100644
--- a/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
+++ b/chrome/test/data/webui/chromeos/os_feedback_ui/share_data_page_test.js
@@ -94,6 +94,7 @@
 
     // Verify the send button is in the page.
     assertEquals('Send', getElementContent('#buttonSend'));
+    assertTrue(page.i18nExists('sendButtonLabel'));
 
     // Verify the attach files label is in the page.
     assertTrue(page.i18nExists('attachFilesLabel'));
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js
index 719c491..d4ff0d9 100644
--- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_devices_subpage_tests.js
@@ -10,7 +10,7 @@
 import {BluetoothSystemProperties, BluetoothSystemState, DeviceConnectionState, SystemPropertiesObserverInterface} from 'chrome://resources/mojo/chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom-webui.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {createDefaultBluetoothDevice, FakeBluetoothConfig} from 'chrome://test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js';
-import {eventToPromise, waitAfterNextRender} from 'chrome://test/test_util.js';
+import {eventToPromise, isVisible, waitAfterNextRender} from 'chrome://test/test_util.js';
 
 import {assertEquals, assertNotEquals, assertTrue} from '../../../chai_assert.js';
 
@@ -72,6 +72,31 @@
     assertTrue(!!bluetoothDevicesSubpage);
   });
 
+  test('Only show saved devices link row when flag is true', async function() {
+    bluetoothConfig.setSystemState(BluetoothSystemState.kEnabled);
+    await init();
+
+    bluetoothDevicesSubpage.remove();
+    // Set flag to True and check that the row is visible.
+    loadTimeData.overrideValues({'enableSavedDevicesFlag': true});
+    bluetoothDevicesSubpage =
+        document.createElement('os-settings-bluetooth-devices-subpage');
+    document.body.appendChild(bluetoothDevicesSubpage);
+    flush();
+    assertTrue(isVisible(bluetoothDevicesSubpage.shadowRoot.querySelector(
+        '#savedDevicesRowLink')));
+
+    bluetoothDevicesSubpage.remove();
+    // Set flag to False and check that the row is not visible.
+    loadTimeData.overrideValues({'enableSavedDevicesFlag': false});
+    bluetoothDevicesSubpage =
+        document.createElement('os-settings-bluetooth-devices-subpage');
+    document.body.appendChild(bluetoothDevicesSubpage);
+    flush();
+    assertFalse(isVisible(bluetoothDevicesSubpage.shadowRoot.querySelector(
+        '#savedDevicesRowLink')));
+  });
+
   test('Toggle button creation and a11y', async function() {
     bluetoothConfig.setSystemState(BluetoothSystemState.kEnabled);
     await init();
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index e9222b7d..d52523b 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -668,7 +668,14 @@
 #endif
 #endif
 
-TEST_F(IntegrationTest, UpdateServiceStress) {
+// TODO(crbug.com/1336591) - enable test after investigating crbug.com/1336591
+// or open a new crbug for debugging this test if it is the culprit.
+#if BUILDFLAG(IS_WIN)
+#define MAYBE_UpdateServiceStress DISABLED_UpdateServiceStress
+#else
+#define MAYBE_UpdateServiceStress UpdateServiceStress
+#endif
+TEST_F(IntegrationTest, MAYBE_UpdateServiceStress) {
   Install();
   ExpectInstalled();
   StressUpdateService();
diff --git a/chromeos/ash/components/memory/userspace_swap/userspace_swap.cc b/chromeos/ash/components/memory/userspace_swap/userspace_swap.cc
index fbf676c..06d01616 100644
--- a/chromeos/ash/components/memory/userspace_swap/userspace_swap.cc
+++ b/chromeos/ash/components/memory/userspace_swap/userspace_swap.cc
@@ -496,7 +496,7 @@
 
   auto& pool_manager = base::internal::AddressPoolManager::GetInstance();
 
-  for (base::internal::pool_handle ph :
+  for (partition_alloc::internal::pool_handle ph :
        {partition_alloc::internal::PartitionAddressSpace::GetRegularPool(),
         partition_alloc::internal::PartitionAddressSpace::GetBRPPool()}) {
     uintptr_t pool_base = pool_manager.GetPoolBaseAddress(ph);
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index d0d312f..8faefaa5 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -3413,6 +3413,9 @@
       <message name="IDS_FEEDBACK_TOOL_USER_EMAIL_LABEL" desc="Label showing the e-mail address that will be reported.">
         Email
       </message>
+      <message name="IDS_FEEDBACK_TOOL_SEND_BUTTON_LABEL" desc="label for the send button to send feedback.">
+        Send
+      </message>
       <message name="IDS_FEEDBACK_TOOL_SHARE_DIAGNOSTIC_DATA_LABEL" desc="Label showing the share diagnostic data.">
         Share diagnostic data
       </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_SEND_BUTTON_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_SEND_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..14da21f
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_FEEDBACK_TOOL_SEND_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+21581966d3d1c22e6ca58a00e132a64de15ca3c6
\ No newline at end of file
diff --git a/chromeos/network/shill_property_util.cc b/chromeos/network/shill_property_util.cc
index 0b970a8f..51e5933 100644
--- a/chromeos/network/shill_property_util.cc
+++ b/chromeos/network/shill_property_util.cc
@@ -32,7 +32,7 @@
 // Replace non UTF8 characters in |str| with a replacement character.
 std::string ValidateUTF8(const std::string& str) {
   std::string result;
-  for (size_t index = 0; index < str.size(); ++index) {
+  for (int32_t index = 0; index < static_cast<int32_t>(str.size()); ++index) {
     base_icu::UChar32 code_point_out;
     bool is_unicode_char = base::ReadUnicodeCharacter(str.c_str(), str.size(),
                                                       &index, &code_point_out);
diff --git a/components/android_autofill/browser/junit/BUILD.gn b/components/android_autofill/browser/junit/BUILD.gn
index 62608cce..9f45be2e1 100644
--- a/components/android_autofill/browser/junit/BUILD.gn
+++ b/components/android_autofill/browser/junit/BUILD.gn
@@ -6,14 +6,12 @@
 import("//build/config/android/rules.gni")
 
 robolectric_library("components_autofill_junit_tests") {
-  testonly = true
   sources = [ "src/org/chromium/components/autofill/AutofillProviderTest.java" ]
   deps = [
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//components/android_autofill/browser:java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn
index 2903479..da8536a 100644
--- a/components/background_task_scheduler/BUILD.gn
+++ b/components/background_task_scheduler/BUILD.gn
@@ -101,7 +101,6 @@
 
   robolectric_library("components_background_task_scheduler_junit_tests") {
     include_android_sdk = false
-    testonly = true
     sources = [
       "internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerImplWithMockTest.java",
       "internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerJobServiceTest.java",
@@ -137,7 +136,6 @@
       "//components/background_task_scheduler:public_java",
       "//content/public/test/android:content_java_test_support",
       "//third_party/android_deps:chromium_play_services_availability_shadows_java",
-      "//third_party/android_deps:robolectric_all_java",
       "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//third_party/robolectric:robolectric_test_sdk_java",
diff --git a/components/browser_ui/accessibility/android/BUILD.gn b/components/browser_ui/accessibility/android/BUILD.gn
index 8049c4650..3fc4dff 100644
--- a/components/browser_ui/accessibility/android/BUILD.gn
+++ b/components/browser_ui/accessibility/android/BUILD.gn
@@ -77,7 +77,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediatorUnitTest.java" ]
 
   deps = [
@@ -86,7 +85,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//content/public/android:content_full_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/components/browser_ui/bottomsheet/android/internal/BUILD.gn b/components/browser_ui/bottomsheet/android/internal/BUILD.gn
index d4b5746a..1ad9220 100644
--- a/components/browser_ui/bottomsheet/android/internal/BUILD.gn
+++ b/components/browser_ui/bottomsheet/android/internal/BUILD.gn
@@ -34,13 +34,11 @@
 }
 
 robolectric_library("junit_tests") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetSwipeDetectorTest.java" ]
   deps = [
     ":java",
     "//base:base_java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/components/browser_ui/client_certificate/android/BUILD.gn b/components/browser_ui/client_certificate/android/BUILD.gn
index 7cbfdc2..cc3e04fef 100644
--- a/components/browser_ui/client_certificate/android/BUILD.gn
+++ b/components/browser_ui/client_certificate/android/BUILD.gn
@@ -47,12 +47,10 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequestTest.java" ]
   deps = [
     ":java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/components/browser_ui/media/android/BUILD.gn b/components/browser_ui/media/android/BUILD.gn
index 84a52dd..dc2781c 100644
--- a/components/browser_ui/media/android/BUILD.gn
+++ b/components/browser_ui/media/android/BUILD.gn
@@ -76,7 +76,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/browser_ui/media/MediaImageManagerTest.java",
     "java/src/org/chromium/components/browser_ui/media/MediaNotificationButtonComputationTest.java",
@@ -89,7 +88,6 @@
     "//content/public/android:content_java",
     "//services/media_session/public/cpp/android:media_session_java",
     "//services/media_session/public/mojom:mojom_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
diff --git a/components/browser_ui/modaldialog/android/BUILD.gn b/components/browser_ui/modaldialog/android/BUILD.gn
index 7ec923b..6dbd65c 100644
--- a/components/browser_ui/modaldialog/android/BUILD.gn
+++ b/components/browser_ui/modaldialog/android/BUILD.gn
@@ -44,19 +44,37 @@
   ]
 }
 
-android_library("javatests") {
+android_library("test_support_java") {
+  testonly = true
+
+  sources = [ "java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogTestUtils.java" ]
+
+  deps = [
+    ":java",
+    ":java_test_resources",
+    "//content/public/test/android:content_java_test_support",
+    "//third_party/android_deps:espresso_java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/junit:junit",
+    "//ui/android:ui_java_test_support",
+    "//ui/android:ui_no_recycler_view_java",
+  ]
+
+  resources_package = "org.chromium.components.browser_ui.modaldialog.test"
+}
+
+android_library("unit_device_javatests") {
   testonly = true
 
   sources = [
     "java/src/org/chromium/components/browser_ui/modaldialog/AppModalPresenterTest.java",
-    "java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogTestUtils.java",
     "java/src/org/chromium/components/browser_ui/modaldialog/ModalDialogViewTest.java",
   ]
 
   deps = [
     ":java",
     ":java_resources",
-    ":java_test_resources",
+    ":test_support_java",
     "//base:base_java_test_support",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:espresso_java",
@@ -69,7 +87,6 @@
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
   ]
-  resources_package = "org.chromium.components.browser_ui.modaldialog.test"
 }
 
 android_resources("java_test_resources") {
diff --git a/components/browser_ui/photo_picker/android/BUILD.gn b/components/browser_ui/photo_picker/android/BUILD.gn
index b354ddd..291530a 100644
--- a/components/browser_ui/photo_picker/android/BUILD.gn
+++ b/components/browser_ui/photo_picker/android/BUILD.gn
@@ -107,7 +107,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/browser_ui/photo_picker/FileEnumWorkerTaskTest.java",
     "java/src/org/chromium/components/browser_ui/photo_picker/PickerBitmapViewTest.java",
@@ -119,7 +118,6 @@
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
     "//net/android:net_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
diff --git a/components/browser_ui/util/android/BUILD.gn b/components/browser_ui/util/android/BUILD.gn
index 72cc328..453bdcf 100644
--- a/components/browser_ui/util/android/BUILD.gn
+++ b/components/browser_ui/util/android/BUILD.gn
@@ -48,7 +48,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/browser_ui/util/BitmapCacheTest.java",
     "java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegateTest.java",
@@ -61,7 +60,6 @@
     "//base/test:test_support_java",
     "//cc:cc_java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/components/browser_ui/webshare/android/BUILD.gn b/components/browser_ui/webshare/android/BUILD.gn
index e6f3510..6354398 100644
--- a/components/browser_ui/webshare/android/BUILD.gn
+++ b/components/browser_ui/webshare/android/BUILD.gn
@@ -25,7 +25,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/browser_ui/webshare/ShareServiceImplTest.java",
     "java/src/org/chromium/components/browser_ui/webshare/SharedFileCollatorTest.java",
@@ -35,7 +34,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
     "//third_party/junit",
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn
index af2945f6..512d51a1 100644
--- a/components/browser_ui/widget/android/BUILD.gn
+++ b/components/browser_ui/widget/android/BUILD.gn
@@ -385,7 +385,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/browser_ui/widget/CompositeTouchDelegateUnitTest.java",
     "java/src/org/chromium/components/browser_ui/widget/ContextMenuDialogUnitTest.java",
@@ -401,7 +400,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
diff --git a/components/content_capture/android/junit/BUILD.gn b/components/content_capture/android/junit/BUILD.gn
index f740b50e..bd23c3c 100644
--- a/components/content_capture/android/junit/BUILD.gn
+++ b/components/content_capture/android/junit/BUILD.gn
@@ -6,7 +6,6 @@
 import("//build/config/android/rules.gni")
 
 robolectric_library("components_content_capture_junit_tests") {
-  testonly = true
   sources = [
     "src/org/chromium/components/content_capture/PlatformAPIWrapperTest.java",
     "src/org/chromium/components/content_capture/PlatformContentCaptureControllerTest.java",
@@ -17,7 +16,6 @@
     "//base:base_junit_test_support",
     "//components/content_capture/android:java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn
index d20c61a..4a4c539 100644
--- a/components/crash/android/BUILD.gn
+++ b/components/crash/android/BUILD.gn
@@ -40,7 +40,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/crash/LogcatCrashExtractorTest.java",
     "junit/src/org/chromium/components/crash/PureJavaExceptionReporterTest.java",
@@ -54,7 +53,6 @@
     "//base:base_junit_test_support",
     "//components/minidump_uploader:minidump_uploader_java_test_support",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
   ]
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index c6066813..31de1a5 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -47,9 +47,6 @@
 generate_jni_registration("cronet_jni_registration") {
   targets = [ ":cronet_impl_native_base_java" ]
   header_output = _jni_registration_header
-
-  # JNI generated is used for test and non-test apks.
-  include_testonly = true
   sources_exclusions = [
     "//base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
     "//base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn
index ab9e8ea..f994548 100644
--- a/components/embedder_support/android/BUILD.gn
+++ b/components/embedder_support/android/BUILD.gn
@@ -291,23 +291,17 @@
 }
 
 robolectric_library("junit_test_support") {
-  testonly = true
   sources = [ "junit/src/org/chromium/components/embedder_support/util/ShadowUrlUtilities.java" ]
-  deps = [
-    ":util_java",
-    "//third_party/android_deps:robolectric_all_java",
-  ]
+  deps = [ ":util_java" ]
 }
 
 robolectric_library("components_embedder_support_junit_tests") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/embedder_support/util/OriginTest.java",
   ]
   deps = [
     ":util_java",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
   ]
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client_unittest.cc b/components/embedder_support/android/metrics/android_metrics_service_client_unittest.cc
index ce83e198..1c5eebb 100644
--- a/components/embedder_support/android/metrics/android_metrics_service_client_unittest.cc
+++ b/components/embedder_support/android/metrics/android_metrics_service_client_unittest.cc
@@ -16,8 +16,10 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_simple_task_runner.h"
+#include "components/metrics/clean_exit_beacon.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
+#include "components/metrics/metrics_state_manager.h"
 #include "components/metrics/metrics_switches.h"
 #include "components/metrics/persistent_histograms.h"
 #include "components/prefs/testing_pref_service.h"
@@ -153,15 +155,27 @@
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
 };
 
-// Verify that the Extended Variations Safe Mode experiment is disabled on
-// Android embedders.
+// Verify that Chrome does not start watching for browser crashes before setting
+// up field trials. For Android embedders, Chrome should not watch for crashes
+// then because, at the time of field trial set-up, it is not possible to know
+// whether the embedder will come to foreground. The embedder may remain in the
+// background for the browser process lifetime, and in this case, Chrome should
+// not watch for crashes so that exiting is not considered a crash. Embedders
+// start watching for crashes when foregrounding via
+// MetricsService::OnAppEnterForeground().
 TEST_F(AndroidMetricsServiceClientTest,
-       ExtendedVariationsSafeModeExperimentDisabled) {
+       DoNotWatchForCrashesBeforeFieldTrialSetUp) {
   auto prefs = CreateTestPrefs();
   auto client = std::make_unique<TestClient>();
   client->Initialize(prefs.get());
-  EXPECT_FALSE(
-      base::FieldTrialList::IsTrialActive(variations::kExtendedSafeModeTrial));
+  EXPECT_TRUE(client->metrics_state_manager()
+                  ->clean_exit_beacon()
+                  ->GetUserDataDirForTesting()
+                  .empty());
+  EXPECT_TRUE(client->metrics_state_manager()
+                  ->clean_exit_beacon()
+                  ->GetBeaconFilePathForTesting()
+                  .empty());
 }
 
 TEST_F(AndroidMetricsServiceClientTest, TestSetConsentTrueBeforeInit) {
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 62035e6..58ec66f7 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -282,6 +282,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 // SurfaceDelegate overrides:
 
+void ShellSurface::OnSetFrame(SurfaceFrameType type) {
+  ShellSurfaceBase::OnSetFrame(type);
+
+  if (!widget_)
+    return;
+  widget_->GetNativeWindow()->SetProperty(
+      aura::client::kUseWindowBoundsForShadow,
+      frame_type_ != SurfaceFrameType::SHADOW);
+}
+
 void ShellSurface::OnSetParent(Surface* parent, const gfx::Point& position) {
   views::Widget* parent_widget =
       parent ? views::Widget::GetTopLevelWidgetForNativeView(parent->window())
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h
index a4533dd..76e6476 100644
--- a/components/exo/shell_surface.h
+++ b/components/exo/shell_surface.h
@@ -107,6 +107,7 @@
   void RemoveObserver(ShellSurfaceObserver* observer);
 
   // Overridden from SurfaceDelegate:
+  void OnSetFrame(SurfaceFrameType type) override;
   void OnSetParent(Surface* parent, const gfx::Point& position) override;
 
   // Overridden from ShellSurfaceBase:
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index fbc0101..2cfc699a 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -1745,8 +1745,6 @@
 
   gfx::Size size = widget->GetWindowBoundsInScreen().size();
   widget->SetBounds(gfx::Rect(size));
-  widget->GetNativeWindow()->SetProperty(
-      aura::client::kUseWindowBoundsForShadow, false);
 
   // Starts mouse event to make sure resize shadow is created.
   ui::test::EventGenerator* event_generator = GetEventGenerator();
@@ -1759,6 +1757,9 @@
   ASSERT_TRUE(resize_shadow);
   shell_surface->root_surface()->SetFrame(SurfaceFrameType::SHADOW);
   shell_surface->root_surface()->Commit();
+  EXPECT_FALSE(widget->GetNativeWindow()->GetProperty(
+      aura::client::kUseWindowBoundsForShadow));
+
   ui::Shadow* normal_shadow =
       wm::ShadowController::GetShadowForWindow(widget->GetNativeWindow());
   ASSERT_TRUE(normal_shadow);
@@ -1826,6 +1827,12 @@
   ASSERT_TRUE(resize_shadow);
   shell_surface->root_surface()->SetFrame(SurfaceFrameType::SHADOW);
   shell_surface->root_surface()->Commit();
+  EXPECT_FALSE(widget->GetNativeWindow()->GetProperty(
+      aura::client::kUseWindowBoundsForShadow));
+  // Override the property to update the shadow bounds immediately.
+  widget->GetNativeWindow()->SetProperty(
+      aura::client::kUseWindowBoundsForShadow, true);
+
   ui::Shadow* normal_shadow =
       wm::ShadowController::GetShadowForWindow(widget->GetNativeWindow());
   ASSERT_TRUE(normal_shadow);
diff --git a/components/externalauth/android/BUILD.gn b/components/externalauth/android/BUILD.gn
index 6c65f49..fe139916 100644
--- a/components/externalauth/android/BUILD.gn
+++ b/components/externalauth/android/BUILD.gn
@@ -43,15 +43,12 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
-
   deps = [
     ":java",
     "$google_play_services_package:google_play_services_basement_java",
     "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/components/gcm_driver/android/BUILD.gn b/components/gcm_driver/android/BUILD.gn
index d6d2e63..f8c4ee63 100644
--- a/components/gcm_driver/android/BUILD.gn
+++ b/components/gcm_driver/android/BUILD.gn
@@ -29,7 +29,6 @@
 }
 
 robolectric_library("components_gcm_driver_junit_tests") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/gcm_driver/GCMMessageTest.java",
     "junit/src/org/chromium/components/gcm_driver/LazySubscriptionsManagerTest.java",
@@ -39,7 +38,6 @@
     "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/junit",
   ]
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims.cc b/components/gwp_asan/client/sampling_partitionalloc_shims.cc
index 6b15d6b..a9a0e408 100644
--- a/components/gwp_asan/client/sampling_partitionalloc_shims.cc
+++ b/components/gwp_asan/client/sampling_partitionalloc_shims.cc
@@ -83,8 +83,8 @@
   sampling_state.Init(sampling_frequency);
   // TODO(vtsyrklevich): Allow SetOverrideHooks to be passed in so we can hook
   // PDFium's PartitionAlloc fork.
-  base::PartitionAllocHooks::SetOverrideHooks(&AllocationHook, &FreeHook,
-                                              &ReallocHook);
+  partition_alloc::PartitionAllocHooks::SetOverrideHooks(
+      &AllocationHook, &FreeHook, &ReallocHook);
 }
 
 }  // namespace internal
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
index 3ae38ad..40dcf10b 100644
--- a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
+++ b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
@@ -68,7 +68,7 @@
  public:
   static void multiprocessTestSetup() {
     crash_reporter::InitializeCrashKeys();
-    base::PartitionAllocGlobalInit(HandleOOM);
+    partition_alloc::PartitionAllocGlobalInit(HandleOOM);
     InstallPartitionAllocHooks(
         AllocatorState::kMaxMetadata, AllocatorState::kMaxMetadata,
         AllocatorState::kMaxSlots, kSamplingFrequency, base::DoNothing());
@@ -87,7 +87,7 @@
 MULTIPROCESS_TEST_MAIN_WITH_SETUP(
     BasicFunctionality,
     SamplingPartitionAllocShimsTest::multiprocessTestSetup) {
-  base::PartitionAllocator allocator;
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kAllocatorOptions);
   for (size_t i = 0; i < kLoopIterations; i++) {
     void* ptr = allocator.root()->Alloc(1, kFakeType);
@@ -107,7 +107,7 @@
 MULTIPROCESS_TEST_MAIN_WITH_SETUP(
     Realloc,
     SamplingPartitionAllocShimsTest::multiprocessTestSetup) {
-  base::PartitionAllocator allocator;
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kAllocatorOptions);
 
   void* alloc = GetPartitionAllocGpaForTesting().Allocate(base::GetPageSize());
@@ -136,7 +136,7 @@
 MULTIPROCESS_TEST_MAIN_WITH_SETUP(
     DifferentTypesDontOverlap,
     SamplingPartitionAllocShimsTest::multiprocessTestSetup) {
-  base::PartitionAllocator allocator;
+  partition_alloc::PartitionAllocator allocator;
   allocator.init(kAllocatorOptions);
 
   std::set<void*> type1, type2;
diff --git a/components/heap_profiling/multi_process/test_driver.cc b/components/heap_profiling/multi_process/test_driver.cc
index 13a547e..78dd5d5 100644
--- a/components/heap_profiling/multi_process/test_driver.cc
+++ b/components/heap_profiling/multi_process/test_driver.cc
@@ -342,7 +342,7 @@
 TestDriver::TestDriver()
     : wait_for_ui_thread_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                           base::WaitableEvent::InitialState::NOT_SIGNALED) {
-  base::PartitionAllocGlobalInit(HandleOOM);
+  partition_alloc::PartitionAllocGlobalInit(HandleOOM);
   partition_allocator_.init({
       base::PartitionOptions::AlignedAlloc::kDisallowed,
       base::PartitionOptions::ThreadCache::kDisabled,
@@ -353,7 +353,7 @@
   });
 }
 TestDriver::~TestDriver() {
-  base::PartitionAllocGlobalUninitForTesting();
+  partition_alloc::PartitionAllocGlobalUninitForTesting();
 }
 
 bool TestDriver::RunTest(const Options& options) {
diff --git a/components/heap_profiling/multi_process/test_driver.h b/components/heap_profiling/multi_process/test_driver.h
index a161860..e52b621 100644
--- a/components/heap_profiling/multi_process/test_driver.h
+++ b/components/heap_profiling/multi_process/test_driver.h
@@ -131,7 +131,7 @@
   size_t total_variadic_allocations_ = 0;
 
   // Use to make PA allocations, which should also be shimmed.
-  base::PartitionAllocator partition_allocator_;
+  partition_alloc::PartitionAllocator partition_allocator_;
 
   // Contains nothing until |CollectResults| has been called.
   std::string serialized_trace_;
diff --git a/components/image_fetcher/BUILD.gn b/components/image_fetcher/BUILD.gn
index 0a8282fe..e107b046 100644
--- a/components/image_fetcher/BUILD.gn
+++ b/components/image_fetcher/BUILD.gn
@@ -51,7 +51,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "android/junit/src/org/chromium/components/image_fetcher/CachedImageFetcherTest.java",
     "android/junit/src/org/chromium/components/image_fetcher/ImageFetcherBridgeTest.java",
@@ -67,7 +66,6 @@
     "//base:jni_java",
     "//components/browser_ui/util/android:java",
     "//components/embedder_support/android:simple_factory_key_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/gif_player:gif_player_java",
diff --git a/components/installedapp/android/BUILD.gn b/components/installedapp/android/BUILD.gn
index ebe98f5..e8d8b20 100644
--- a/components/installedapp/android/BUILD.gn
+++ b/components/installedapp/android/BUILD.gn
@@ -64,7 +64,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources =
       [ "java/src/org/chromium/components/installedapp/PackageHashTest.java" ]
   deps = [
diff --git a/components/language/android/BUILD.gn b/components/language/android/BUILD.gn
index 382c9c63..43102201 100644
--- a/components/language/android/BUILD.gn
+++ b/components/language/android/BUILD.gn
@@ -68,7 +68,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/language/LanguageProfileControllerUnitTest.java" ]
   deps = [
     ":java",
@@ -79,7 +78,6 @@
     "//components/browser_ui/widget/android:java",
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/components/media_router/browser/android/BUILD.gn b/components/media_router/browser/android/BUILD.gn
index aa502cf..a6ef481 100644
--- a/components/media_router/browser/android/BUILD.gn
+++ b/components/media_router/browser/android/BUILD.gn
@@ -120,7 +120,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/media_router/BrowserMediaRouterRouteTest.java",
     "junit/src/org/chromium/components/media_router/BrowserMediaRouterSinkObservationTest.java",
@@ -149,7 +148,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_mediarouter_mediarouter_java",
     "//third_party/junit",
diff --git a/components/messages/android/BUILD.gn b/components/messages/android/BUILD.gn
index 092ef31..8a34a8d 100644
--- a/components/messages/android/BUILD.gn
+++ b/components/messages/android/BUILD.gn
@@ -129,7 +129,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources =
       [ "java/src/org/chromium/components/messages/MessageWrapperTest.java" ]
   deps = [
@@ -138,7 +137,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//components/browser_ui/widget/android:java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
diff --git a/components/messages/android/internal/BUILD.gn b/components/messages/android/internal/BUILD.gn
index d91f9f4..d1544a2f 100644
--- a/components/messages/android/internal/BUILD.gn
+++ b/components/messages/android/internal/BUILD.gn
@@ -41,7 +41,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/messages/MessageAutoDismissTimerTest.java",
     "java/src/org/chromium/components/messages/MessageBannerCoordinatorUnitTest.java",
@@ -60,7 +59,6 @@
     "//components/browser_ui/widget/android:java",
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
@@ -68,7 +66,7 @@
   ]
 }
 
-android_library("javatests") {
+android_library("unit_device_javatests") {
   testonly = true
   sources = [
     "java/src/org/chromium/components/messages/MessageBannerRenderTest.java",
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java
index 0fb6abd..41c3353 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java
@@ -4,6 +4,9 @@
 
 package org.chromium.components.messages;
 
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_LOW_END_DEVICE;
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
+
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -23,12 +26,15 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.BaseSwitches;
 import org.chromium.base.test.params.BaseJUnit4RunnerDelegate;
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.base.test.params.ParameterizedRunner;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
@@ -61,6 +67,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testBasic() throws Exception {
         Activity activity = getActivity();
         Drawable drawable = ApiCompatibilityUtils.getDrawable(
@@ -87,6 +94,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testBasic_withSecondaryIcon() throws Exception {
         Activity activity = getActivity();
         Drawable drawable = ApiCompatibilityUtils.getDrawable(
@@ -116,6 +124,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testBasic_withSpannableDescription() throws Exception {
         Activity activity = getActivity();
         Drawable drawable = ApiCompatibilityUtils.getDrawable(
@@ -145,6 +154,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testBasic_multilineDescriptionMaxLines() throws Exception {
         Activity activity = getActivity();
         final String multilineDescription = "Line 1\nLine 2\nLine 3\nLine 4";
@@ -171,6 +181,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testLayoutAfterClearingDescription() throws Exception {
         Activity activity = getActivity();
         Drawable drawable = ApiCompatibilityUtils.getDrawable(
@@ -198,6 +209,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testLargeIcon() throws Exception {
         Activity activity = getActivity();
         Drawable drawable = ApiCompatibilityUtils.getDrawable(
@@ -225,6 +237,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testLargeIconWithRadius() throws Exception {
         Activity activity = getActivity();
         Bitmap.Config conf = Bitmap.Config.ARGB_8888;
@@ -258,6 +271,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testDescriptionIconWithDefaultSize() throws Exception {
         Activity activity = getActivity();
         Drawable messageIcon = ApiCompatibilityUtils.getDrawable(
@@ -287,6 +301,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testDescriptionIconWithResizing() throws Exception {
         Activity activity = getActivity();
         Drawable messageIcon = ApiCompatibilityUtils.getDrawable(
@@ -317,6 +332,7 @@
     @Test
     @SmallTest
     @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testDescriptionIconWithText() throws Exception {
         Activity activity = getActivity();
         Drawable messageIcon = ApiCompatibilityUtils.getDrawable(
@@ -344,4 +360,32 @@
                 () -> { getActivity().setContentView(view, params); });
         mRenderTestRule.render(view, "message_banner_description_icon_with_text");
     }
-}
\ No newline at end of file
+
+    @Test
+    @SmallTest
+    @Feature({"RenderTest", "Messages"})
+    @Restriction({RESTRICTION_TYPE_LOW_END_DEVICE})
+    @CommandLineFlags.Add(BaseSwitches.ENABLE_LOW_END_DEVICE_MODE)
+    public void testBasic_lowEnd() throws Exception {
+        Activity activity = getActivity();
+        Drawable drawable = ApiCompatibilityUtils.getDrawable(
+                activity.getResources(), android.R.drawable.ic_delete);
+        PropertyModel model = new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                                      .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                              MessageIdentifier.TEST_MESSAGE)
+                                      .with(MessageBannerProperties.ICON, drawable)
+                                      .with(MessageBannerProperties.TITLE, "Primary Title")
+                                      .with(MessageBannerProperties.DESCRIPTION, "Secondary Title")
+                                      .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, "Action")
+                                      .build();
+        MessageBannerView view = (MessageBannerView) LayoutInflater.from(activity).inflate(
+                R.layout.message_banner_view, null, false);
+        PropertyModelChangeProcessor.create(model, view, MessageBannerViewBinder::bind);
+        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
+                activity.getResources().getDimensionPixelSize(R.dimen.message_banner_height));
+
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { getActivity().setContentView(view, params); });
+        mRenderTestRule.render(view, "message_banner_basic_low_end");
+    }
+}
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
index 1c142c2..69bef22 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
@@ -22,6 +22,7 @@
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.SysUtils;
 import org.chromium.components.browser_ui.widget.BoundedLinearLayout;
 import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener;
 import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler;
@@ -73,6 +74,10 @@
         mSecondaryButton = findViewById(R.id.message_secondary_button);
         mDivider = findViewById(R.id.message_divider);
         mSecondaryButton.setOnClickListener((View v) -> { handleSecondaryButtonClick(); });
+        // Elevation does not work on low end device.
+        if (SysUtils.isLowEndDevice()) {
+            setBackgroundResource(R.drawable.popup_bg);
+        }
     }
 
     void setTitle(String title) {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
index 718654d8..ee96de6 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
@@ -30,6 +30,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.test.BaseActivityTestRule;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -40,6 +41,7 @@
  * Tests for {@link SingleActionMessage}.
  */
 @RunWith(BaseJUnit4ClassRunner.class)
+@Batch(Batch.UNIT_TESTS)
 public class SingleActionMessageTest {
     @ClassRule
     public static DisableAnimationsTestRule sDisableAnimationsRule =
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc
index 7a9ecaa..1ace9540 100644
--- a/components/metrics/clean_exit_beacon.cc
+++ b/components/metrics/clean_exit_beacon.cc
@@ -184,43 +184,7 @@
   return beacon_file_contents;
 }
 
-// Returns the channel to use for setting up the Extended Variations Safe Mode
-// experiment.
-//
-// This is needed for tests in which there is a mismatch between (a) the channel
-// on which the bot is running (and thus the channel plumbed through to the
-// CleanExitBeacon's ctor) and (b) the channel that we wish to use for running a
-// particular test. This mismatch can cause failures (crbug/1259550) when (a)
-// the channel on which the bot is running is a channel to which the Extended
-// Variations Safe Mode experiment does not apply and (b) a test uses a channel
-// on which the experiment does apply.
-//
-// TODO(crbug/1241702): Clean up this function once the experiment is over.
-version_info::Channel GetChannel(version_info::Channel channel) {
-  const std::string forced_channel =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          variations::switches::kFakeVariationsChannel);
-
-  if (!forced_channel.empty()) {
-    if (forced_channel == "stable")
-      return version_info::Channel::STABLE;
-    if (forced_channel == "beta")
-      return version_info::Channel::BETA;
-    if (forced_channel == "dev")
-      return version_info::Channel::DEV;
-    if (forced_channel == "canary")
-      return version_info::Channel::CANARY;
-    DVLOG(1) << "Invalid channel provided: " << forced_channel;
-  }
-  return channel;
-}
-
-// Sets up the Extended Variations Safe Mode experiment, whose groups have
-// platform- and channel-specific weights. Returns the name of the client's
-// experiment group name, e.g. "Control".
-// TODO(crbug/1241702): Remove this once the experiment launches on Android
-// Chrome.
-std::string SetUpExtendedSafeModeTrial(version_info::Channel channel) {
+std::string SetUpExtendedSafeModeTrial() {
   int default_group;
   scoped_refptr<base::FieldTrial> trial(
       base::FieldTrialList::FactoryGetFieldTrial(
@@ -244,7 +208,7 @@
       local_state_(local_state),
       initial_browser_last_live_timestamp_(
           local_state->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp)),
-      channel_(GetChannel(channel)) {
+      channel_(channel) {
   DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING,
             local_state_->GetInitializationStatus());
 }
@@ -256,11 +220,13 @@
   if (!user_data_dir_.empty()) {
     // Platforms that pass an empty path do so deliberately. They should not
     // participate in this experiment.
-    group = SetUpExtendedSafeModeTrial(channel_);
+    group = SetUpExtendedSafeModeTrial();
   }
 
-  if (group == kEnabledGroup)
-    beacon_file_path_ = user_data_dir_.Append(variations::kVariationsFilename);
+  if (group == kEnabledGroup) {
+    beacon_file_path_ =
+        user_data_dir_.Append(variations::kCleanExitBeaconFilename);
+  }
 
   std::unique_ptr<base::Value> beacon_file_contents =
       MaybeGetFileContents(beacon_file_path_);
@@ -423,6 +389,14 @@
                         base::Time::Now());
 }
 
+const base::FilePath CleanExitBeacon::GetUserDataDirForTesting() const {
+  return user_data_dir_;
+}
+
+base::FilePath CleanExitBeacon::GetBeaconFilePathForTesting() const {
+  return beacon_file_path_;
+}
+
 // static
 void CleanExitBeacon::RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
diff --git a/components/metrics/clean_exit_beacon.h b/components/metrics/clean_exit_beacon.h
index e6bc1619..8a560a6 100644
--- a/components/metrics/clean_exit_beacon.h
+++ b/components/metrics/clean_exit_beacon.h
@@ -108,6 +108,9 @@
   // Updates the last live timestamp.
   void UpdateLastLiveTimestamp();
 
+  const base::FilePath GetUserDataDirForTesting() const;
+  base::FilePath GetBeaconFilePathForTesting() const;
+
   // Registers local state prefs used by this class.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
@@ -200,7 +203,7 @@
   // 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.
-  const version_info::Channel channel_;
+  [[maybe_unused]] const version_info::Channel channel_;
 
   bool did_previous_session_exit_cleanly_ = false;
 
diff --git a/components/metrics/clean_exit_beacon_unittest.cc b/components/metrics/clean_exit_beacon_unittest.cc
index 8a2cb80..ebea3d5 100644
--- a/components/metrics/clean_exit_beacon_unittest.cc
+++ b/components/metrics/clean_exit_beacon_unittest.cc
@@ -211,7 +211,7 @@
   // were used, then the prefs' values would change.)
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath temp_beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   ASSERT_LT(0, base::WriteFile(temp_beacon_file_path,
                                CreateWellFormedBeaconFileContents(
                                    /*exited_cleanly=*/false, /*crash_streak=*/2)
@@ -278,7 +278,7 @@
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   if (params.beacon_file_exists) {
     const base::FilePath temp_beacon_file_path =
-        user_data_dir_path.Append(variations::kVariationsFilename);
+        user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
     ASSERT_LT(0, base::WriteFile(temp_beacon_file_path,
                                  params.beacon_file_contents.data()));
   }
@@ -296,7 +296,7 @@
   SetUpExtendedSafeModeExperiment(variations::kEnabledGroup);
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath temp_beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   const int num_crashes = 2;
   ASSERT_LT(0, base::WriteFile(
                    temp_beacon_file_path,
@@ -320,7 +320,7 @@
   SetUpExtendedSafeModeExperiment(variations::kEnabledGroup);
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath temp_beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   const int last_session_num_crashes = 2;
   ASSERT_LT(0, base::WriteFile(temp_beacon_file_path,
                                CreateWellFormedBeaconFileContents(
@@ -394,7 +394,7 @@
   // is considered missing.
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath temp_beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   ASSERT_FALSE(base::PathExists(temp_beacon_file_path));
   // Clear the Local State beacon. Unless set below, it is also considered
   // missing.
@@ -428,7 +428,7 @@
 TEST_F(CleanExitBeaconTest, WriteBeaconValueWhenNotExitingCleanly) {
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   ASSERT_FALSE(base::PathExists(beacon_file_path));
 
   SetUpExtendedSafeModeExperiment(variations::kEnabledGroup);
@@ -472,7 +472,7 @@
 TEST_F(CleanExitBeaconTest, WriteBeaconValueWhenExitingCleanly) {
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   ASSERT_FALSE(base::PathExists(beacon_file_path));
 
   SetUpExtendedSafeModeExperiment(variations::kEnabledGroup);
@@ -674,7 +674,7 @@
   // is considered missing.
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
   const base::FilePath temp_beacon_file_path =
-      user_data_dir_path.Append(variations::kVariationsFilename);
+      user_data_dir_path.Append(variations::kCleanExitBeaconFilename);
   ASSERT_FALSE(base::PathExists(temp_beacon_file_path));
   // Clear the platform-specific beacon. Unless set below, this beacon is also
   // considered missing.
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn
index fd27a52..05144417 100644
--- a/components/payments/content/android/BUILD.gn
+++ b/components/payments/content/android/BUILD.gn
@@ -310,7 +310,6 @@
 }
 
 robolectric_library("junit_test_support") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/payments/test_support/PaymentRequestServiceBuilder.java",
     "junit/src/org/chromium/components/payments/test_support/ShadowPaymentFeatureList.java",
@@ -321,7 +320,6 @@
     "//components/payments/content/android:service_java",
     "//components/payments/mojom:mojom_java",
     "//content/public/android:content_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_collection_collection_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
@@ -334,7 +332,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/payments/PaymentRequestServiceTest.java",
     "junit/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnTest.java",
@@ -351,7 +348,6 @@
     "//content/public/android:content_java",
     "//mojo/public/java:system_java",
     "//third_party/android_deps:material_design_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_collection_collection_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
     "//third_party/junit",
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc
index 083b312..6faecc06 100644
--- a/components/pdf/renderer/pdf_accessibility_tree.cc
+++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -250,9 +250,8 @@
     int char_index) {
   std::string chars_utf8;
   for (uint32_t i = 0; i < text_run.len; ++i) {
-    base::WriteUnicodeCharacter(
-        static_cast<base_icu::UChar32>(chars[char_index + i].unicode_character),
-        &chars_utf8);
+    base::WriteUnicodeCharacter(chars[char_index + i].unicode_character,
+                                &chars_utf8);
   }
   return chars_utf8;
 }
diff --git a/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc b/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc
index c70f87b6..f1e2368 100644
--- a/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc
+++ b/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc
@@ -132,10 +132,7 @@
   EXPECT_EQ(worker,
             registry_->GetWorkerNodeByWorkerToken(worker->worker_token()));
 
-  // Querying an invalid token or a random token should fail.
-  EXPECT_FALSE(
-      registry_->GetExecutionContextByToken(blink::ExecutionContextToken(
-          blink::LocalFrameToken(base::UnguessableToken::Null()))));
+  // Querying a random token should fail.
   EXPECT_FALSE(
       registry_->GetExecutionContextByToken(blink::ExecutionContextToken()));
   EXPECT_FALSE(registry_->GetFrameNodeByFrameToken(blink::LocalFrameToken()));
diff --git a/components/permissions/android/BUILD.gn b/components/permissions/android/BUILD.gn
index f8e877a..8f22fc3 100644
--- a/components/permissions/android/BUILD.gn
+++ b/components/permissions/android/BUILD.gn
@@ -153,7 +153,6 @@
 }
 
 robolectric_library("components_permissions_junit_tests") {
-  testonly = true
   sources = [ "junit/src/org/chromium/components/permissions/nfc/NfcSystemLevelPromptTest.java" ]
   deps = [
     ":java",
@@ -161,7 +160,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//components/browser_ui/theme/android:java_resources",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
diff --git a/components/policy/android/BUILD.gn b/components/policy/android/BUILD.gn
index c2f1b8c..47db5c0c 100644
--- a/components/policy/android/BUILD.gn
+++ b/components/policy/android/BUILD.gn
@@ -60,7 +60,6 @@
 }
 
 robolectric_library("components_policy_junit_tests") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/policy/AbstractAppRestrictionsProviderTest.java",
     "junit/src/org/chromium/components/policy/CombinedPolicyProviderTest.java",
@@ -76,7 +75,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//build/android:build_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/junit",
diff --git a/components/prefs/android/BUILD.gn b/components/prefs/android/BUILD.gn
index 8be793b..63ff474 100644
--- a/components/prefs/android/BUILD.gn
+++ b/components/prefs/android/BUILD.gn
@@ -19,14 +19,12 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/prefs/PrefServiceTest.java" ]
   deps = [
     ":java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/components/query_tiles/BUILD.gn b/components/query_tiles/BUILD.gn
index cf02ffa..8f96537 100644
--- a/components/query_tiles/BUILD.gn
+++ b/components/query_tiles/BUILD.gn
@@ -134,7 +134,6 @@
   }
 
   robolectric_library("query_tiles_junit_tests") {
-    testonly = true
     sources = [ "android/java/src/org/chromium/components/query_tiles/TileUmaLoggerTest.java" ]
 
     deps = [
@@ -142,7 +141,6 @@
       ":test_support_java",
       "//base:base_java",
       "//base:base_junit_test_support",
-      "//third_party/android_deps:robolectric_all_java",
       "//third_party/junit",
     ]
   }
diff --git a/components/services/app_service/public/cpp/intent_util.cc b/components/services/app_service/public/cpp/intent_util.cc
index cf52369..1de9866 100644
--- a/components/services/app_service/public/cpp/intent_util.cc
+++ b/components/services/app_service/public/cpp/intent_util.cc
@@ -148,6 +148,16 @@
   return intent;
 }
 
+apps::IntentPtr MakeIntentForActivity(const std::string& activity,
+                                      const std::string& start_type,
+                                      const std::string& category) {
+  auto intent = std::make_unique<apps::Intent>(kIntentActionMain);
+  intent->activity_name = activity;
+  intent->start_type = start_type;
+  intent->categories = std::vector<std::string>{category};
+  return intent;
+}
+
 apps::mojom::IntentPtr CreateIntentFromUrl(const GURL& url) {
   auto intent = apps::mojom::Intent::New();
   intent->action = kIntentActionView;
diff --git a/components/services/app_service/public/cpp/intent_util.h b/components/services/app_service/public/cpp/intent_util.h
index 07a8305..a673b8b 100644
--- a/components/services/app_service/public/cpp/intent_util.h
+++ b/components/services/app_service/public/cpp/intent_util.h
@@ -60,6 +60,11 @@
 apps::IntentPtr MakeEditIntent(const GURL& filesystem_url,
                                const std::string& mime_type);
 
+// Create an intent struct from activity and start type.
+apps::IntentPtr MakeIntentForActivity(const std::string& activity,
+                                      const std::string& start_type,
+                                      const std::string& category);
+
 // TODO(crbug.com/1253250): Remove below functions after migrating to non-mojo
 // AppService.
 
diff --git a/components/signin/public/android/BUILD.gn b/components/signin/public/android/BUILD.gn
index 0983c4c..32b09337 100644
--- a/components/signin/public/android/BUILD.gn
+++ b/components/signin/public/android/BUILD.gn
@@ -149,7 +149,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java",
     "junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java",
@@ -170,7 +169,6 @@
     "//components/externalauth/android:java",
     "//testing/android/junit:junit_test_support",
     "//third_party/android_deps:guava_android_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_rules_java",
     "//third_party/junit",
diff --git a/components/subresource_filter/android/BUILD.gn b/components/subresource_filter/android/BUILD.gn
index b532eadb..8d4defc 100644
--- a/components/subresource_filter/android/BUILD.gn
+++ b/components/subresource_filter/android/BUILD.gn
@@ -35,14 +35,12 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [ "java/src/org/chromium/components/subresource_filter/AdsBlockedDialogTest.java" ]
 
   deps = [
     ":java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/components/variations/android/BUILD.gn b/components/variations/android/BUILD.gn
index 08335bfc..b18a819 100644
--- a/components/variations/android/BUILD.gn
+++ b/components/variations/android/BUILD.gn
@@ -25,7 +25,6 @@
 }
 
 robolectric_library("components_variations_junit_tests") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/components/variations/VariationsCompressionUtilsTest.java",
     "junit/src/org/chromium/components/variations/firstrun/VariationsSeedFetcherTest.java",
@@ -38,7 +37,6 @@
     "//components/variations:variations_java",
     "//components/variations/proto:proto_java",
     "//third_party/android_deps:protobuf_lite_runtime_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/components/variations/service/variations_field_trial_creator_unittest.cc b/components/variations/service/variations_field_trial_creator_unittest.cc
index 24cebd2..2242d0b 100644
--- a/components/variations/service/variations_field_trial_creator_unittest.cc
+++ b/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -1299,7 +1299,7 @@
 
   // Verify that the beacon file does not exist.
   EXPECT_FALSE(base::PathExists(
-      user_data_dir_path().Append(variations::kVariationsFilename)));
+      user_data_dir_path().Append(variations::kCleanExitBeaconFilename)));
 }
 
 TEST_F(FieldTrialCreatorSafeModeExperimentTest,
@@ -1331,7 +1331,7 @@
 
   // Verify that the beacon file was written and that the contents are correct.
   const base::FilePath variations_file_path =
-      user_data_dir_path().Append(variations::kVariationsFilename);
+      user_data_dir_path().Append(variations::kCleanExitBeaconFilename);
   EXPECT_TRUE(base::PathExists(variations_file_path));
   std::string beacon_file_contents;
   ASSERT_TRUE(
diff --git a/components/variations/service/variations_safe_mode_constants.cc b/components/variations/service/variations_safe_mode_constants.cc
index ccc66d5d..a48e06b 100644
--- a/components/variations/service/variations_safe_mode_constants.cc
+++ b/components/variations/service/variations_safe_mode_constants.cc
@@ -6,7 +6,7 @@
 
 namespace variations {
 
-const base::FilePath::CharType kVariationsFilename[] =
+const base::FilePath::CharType kCleanExitBeaconFilename[] =
     FILE_PATH_LITERAL("Variations");
 
 const char kExtendedSafeModeTrial[] = "ExtendedVariationsSafeMode5";
diff --git a/components/variations/service/variations_safe_mode_constants.h b/components/variations/service/variations_safe_mode_constants.h
index 0cec908..b284b49 100644
--- a/components/variations/service/variations_safe_mode_constants.h
+++ b/components/variations/service/variations_safe_mode_constants.h
@@ -11,10 +11,9 @@
 
 namespace variations {
 
-// The name of the file, which is relative to the user data directory, used by
-// the Extended Variations Safe Mode experiment's SignalAndWriteViaFileUtilGroup
-// to store the stability beacon and the variations crash streak.
-extern const base::FilePath::CharType kVariationsFilename[];
+// The name of the beacon file, which is relative to the user data directory
+// and used to store the CleanExitBeacon value and the variations crash streak.
+extern const base::FilePath::CharType kCleanExitBeaconFilename[];
 
 // Trial and group names for the extended variations safe mode experiment.
 extern const char kExtendedSafeModeTrial[];
diff --git a/components/webapk/android/libs/client/BUILD.gn b/components/webapk/android/libs/client/BUILD.gn
index 894ea07..e0c283f 100644
--- a/components/webapk/android/libs/client/BUILD.gn
+++ b/components/webapk/android/libs/client/BUILD.gn
@@ -18,7 +18,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "src/org/chromium/components/webapk/lib/client/WebApkValidatorTest.java",
     "src/org/chromium/components/webapk/lib/client/WebApkVerifySignatureTest.java",
@@ -30,7 +29,6 @@
     "//base/test:test_support_java",
     "//components/webapk/android/libs/common:java",
     "//testing/android/junit:junit_test_support",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
   ]
 }
diff --git a/components/webapps/browser/android/BUILD.gn b/components/webapps/browser/android/BUILD.gn
index 6c325d81..2612188 100644
--- a/components/webapps/browser/android/BUILD.gn
+++ b/components/webapps/browser/android/BUILD.gn
@@ -162,7 +162,6 @@
 }
 
 robolectric_library("junit") {
-  testonly = true
   sources = [
     "java/src/org/chromium/components/webapps/AddToHomescreenDialogViewTest.java",
     "java/src/org/chromium/components/webapps/AddToHomescreenMediatorTest.java",
@@ -173,7 +172,6 @@
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
diff --git a/content/app/content_main_runner_impl_browsertest.cc b/content/app/content_main_runner_impl_browsertest.cc
deleted file mode 100644
index 1356879..0000000
--- a/content/app/content_main_runner_impl_browsertest.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/task/thread_pool/thread_pool_instance.h"
-#include "base/test/scoped_field_trial_list_resetter.h"
-#include "build/buildflag.h"
-#include "content/browser/startup_helper.h"
-#include "content/public/app/content_main_delegate.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/gpu/content_gpu_client.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/public/test/browser_test.h"
-#include "content/public/test/content_browser_test.h"
-#include "content/public/utility/content_utility_client.h"
-#include "sandbox/policy/switches.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/variant.h"
-
-namespace variations {
-class VariationsIdsProvider;
-};
-
-namespace content {
-
-class ContentClient;
-
-namespace {
-
-using ::testing::_;
-using ::testing::AtMost;
-using ::testing::ByMove;
-using ::testing::DoAll;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::SetArgPointee;
-using InvokedIn = ContentMainDelegate::InvokedIn;
-
-#if BUILDFLAG(IS_ANDROID)
-// TODO(joenotcharles): Find out why this test crashes on Android, which uses
-// custom startup code in BrowserTestBase::SetUp instead of calling ContentMain.
-#error This test is not supported on Android.
-#endif
-
-// Mocks only the cross-platform methods of ContentMainDelegate.
-class MockContentMainDelegate : public ContentMainDelegate {
- public:
-  MOCK_METHOD(bool, BasicStartupComplete, (int*), (override));
-  MOCK_METHOD(void, PreSandboxStartup, (), (override));
-  MOCK_METHOD(void, SandboxInitialized, (const std::string&), (override));
-  MOCK_METHOD((absl::variant<int, MainFunctionParams>),
-              RunProcess,
-              (const std::string&, MainFunctionParams),
-              (override));
-  MOCK_METHOD(void, ProcessExiting, (const std::string&), (override));
-  MOCK_METHOD(int, TerminateForFatalInitializationError, (), (override));
-  MOCK_METHOD(bool, ShouldLockSchemeRegistry, (), (override));
-  MOCK_METHOD(void, PreBrowserMain, (), (override));
-  MOCK_METHOD(bool, ShouldCreateFeatureList, (InvokedIn), (override));
-  MOCK_METHOD(variations::VariationsIdsProvider*,
-              CreateVariationsIdsProvider,
-              (),
-              (override));
-  MOCK_METHOD(void, PostEarlyInitialization, (InvokedIn), (override));
-  MOCK_METHOD(ContentClient*, CreateContentClient, (), (override));
-  MOCK_METHOD(ContentBrowserClient*,
-              CreateContentBrowserClient,
-              (),
-              (override));
-  MOCK_METHOD(ContentGpuClient*, CreateContentGpuClient, (), (override));
-  MOCK_METHOD(ContentRendererClient*,
-              CreateContentRendererClient,
-              (),
-              (override));
-  MOCK_METHOD(ContentUtilityClient*,
-              CreateContentUtilityClient,
-              (),
-              (override));
-};
-
-// Parameters to control the expectations for MockContentMainDelegate. Each test
-// case uses a different set of parameters, since the expectations need to be
-// installed before SetUp() is called.
-struct MockExpectations {
-  bool exit_after_basic_startup = false;
-  bool content_main_should_create_feature_list = true;
-};
-
-std::ostream& operator<<(std::ostream& os, const MockExpectations& m) {
-  return os << "exit_after_basic_startup:" << m.exit_after_basic_startup
-            << ",content_main_should_create_feature_list:"
-            << m.content_main_should_create_feature_list;
-}
-
-// Tests that methods of ContentMainDelegate are called in the expected order.
-// The string parameter is the process name (empty for the browser process).
-class ContentMainRunnerImplBrowserTest
-    : public ContentBrowserTest,
-      public ::testing::WithParamInterface<
-          std::tuple<std::string, MockExpectations>> {
- protected:
-  ContentMainRunnerImplBrowserTest() {
-    std::string process_type;
-    std::tie(process_type, mock_expectations_) = GetParam();
-
-    // Start without a feature list so the startup sequence can create one.
-    // `scoped_field_trial_list_resetter_` will do the same for the field trial
-    // list.
-    original_feature_list_ = base::FeatureList::ClearInstanceForTesting();
-
-    const bool is_browser_process = process_type.empty();
-    if (!is_browser_process) {
-      // Fool ContentMain() into thinking this is a different process type.
-      base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-      command_line->AppendSwitchASCII(switches::kProcessType, process_type);
-      command_line->AppendSwitch(sandbox::policy::switches::kNoSandbox);
-    }
-    const InvokedIn invoked_in = is_browser_process
-                                     ? InvokedIn::kBrowserProcessUnderTest
-                                     : InvokedIn::kChildProcess;
-
-    // These methods may or may not be called, depending on configuration.
-    EXPECT_CALL(mock_delegate_, ShouldLockSchemeRegistry()).Times(AtMost(1));
-    EXPECT_CALL(mock_delegate_, CreateVariationsIdsProvider()).Times(AtMost(1));
-    // CreateContentClient() is only called if GetContentClient() returns null.
-    EXPECT_CALL(mock_delegate_, CreateContentClient()).Times(AtMost(1));
-
-    // Expect the following entry points to be called, in order.
-    //
-    // BrowserTestBase::SetUp() calls ContentMain(), which instantiates a
-    // ContentMainRunnerImpl, which calls the entry points in
-    // ContentMainDelegate. So test expectations must be installed before
-    // calling the inherited SetUp().
-    ::testing::InSequence s;
-    EXPECT_CALL(mock_delegate_, BasicStartupComplete(_))
-        .WillOnce(DoAll(
-            // Set the exit code.
-            SetArgPointee<0>(0),
-            // Set the return value.
-            Return(mock_expectations_.exit_after_basic_startup)));
-    if (mock_expectations_.exit_after_basic_startup) {
-      // Expect no more calls.
-      return;
-    }
-
-    if (is_browser_process) {
-      EXPECT_CALL(mock_delegate_, CreateContentBrowserClient())
-          .WillOnce(Return(&content_browser_client_));
-    } else if (process_type == switches::kGpuProcess) {
-      EXPECT_CALL(mock_delegate_, CreateContentGpuClient())
-          .WillOnce(Return(&content_gpu_client_));
-    } else if (process_type == switches::kRendererProcess) {
-      EXPECT_CALL(mock_delegate_, CreateContentRendererClient())
-          .WillOnce(Return(&content_renderer_client_));
-    } else {
-      EXPECT_CALL(mock_delegate_, CreateContentUtilityClient())
-          .WillOnce(Return(&content_utility_client_));
-    }
-    EXPECT_CALL(mock_delegate_, PreSandboxStartup());
-    EXPECT_CALL(mock_delegate_, SandboxInitialized(process_type));
-    EXPECT_CALL(mock_delegate_, ShouldCreateFeatureList(invoked_in))
-        .WillOnce(
-            Return(mock_expectations_.content_main_should_create_feature_list));
-    // PreBrowserMain is only called in the browser process.
-    EXPECT_CALL(mock_delegate_, PreBrowserMain())
-        .Times(is_browser_process ? 1 : 0);
-    EXPECT_CALL(mock_delegate_, PostEarlyInitialization(invoked_in))
-        .WillOnce(Invoke(
-            this, &ContentMainRunnerImplBrowserTest::PostEarlyInitialization));
-    EXPECT_CALL(mock_delegate_, RunProcess(process_type, _))
-        .WillOnce(Return(ByMove(0)));
-    EXPECT_CALL(mock_delegate_, ProcessExiting(process_type));
-  }
-
-  ~ContentMainRunnerImplBrowserTest() override {
-    // Restore the original feature list for other tests. Any temporary
-    // FeatureList created during the test (by ContentMainRunnerImpl or
-    // PostEarlyInitialization, depending on the value of the
-    // `content_main_should_create_feature_list` parameter) must be removed
-    // first.
-    base::FeatureList::ClearInstanceForTesting();
-    base::FeatureList::RestoreInstanceForTesting(
-        std::move(original_feature_list_));
-  }
-
-  ContentMainDelegate* GetCustomContentMainDelegate() override {
-    return &mock_delegate_;
-  }
-
-  void PostEarlyInitialization() {
-    ASSERT_TRUE(base::ThreadPoolInstance::Get());
-    if (mock_expectations_.content_main_should_create_feature_list) {
-      ASSERT_TRUE(base::FeatureList::GetInstance());
-    } else {
-      ASSERT_FALSE(base::FeatureList::GetInstance());
-
-      // ContentMainRunnerImpl will try to use the feature list after
-      // PostEarlyInitialization, so we need to create one.
-      field_trials_ = SetUpFieldTrialsAndFeatureList();
-    }
-  }
-
-  ::testing::StrictMock<MockContentMainDelegate> mock_delegate_;
-  MockExpectations mock_expectations_;
-
-  // Stubs to return from CreateContent*Client mocks. These will be deleted at
-  // the end of the test to satisfy the leak checker.
-  ContentBrowserClient content_browser_client_;
-  ContentGpuClient content_gpu_client_;
-  ContentRendererClient content_renderer_client_;
-  ContentUtilityClient content_utility_client_;
-
-  // Ensure that the test can create its own `field_trials_`.
-  base::test::ScopedFieldTrialListResetter scoped_field_trial_list_resetter_;
-  std::unique_ptr<base::FeatureList> original_feature_list_;
-  std::unique_ptr<base::FieldTrialList> field_trials_;
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    ContentMainRunnerImplBrowserTest,
-    ::testing::Combine(
-        ::testing::Values("",
-                          switches::kGpuProcess,
-                          switches::kRendererProcess,
-                          switches::kUtilityProcess),
-        ::testing::Values(MockExpectations{},
-                          MockExpectations{
-                              .content_main_should_create_feature_list = false},
-                          MockExpectations{.exit_after_basic_startup = true})));
-
-IN_PROC_BROWSER_TEST_P(ContentMainRunnerImplBrowserTest, StartupSequence) {
-  // All of the work is done in the test suite constructor and SetUp().
-}
-
-}  // namespace
-
-}  // namespace content
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index c6a6501..d5c7949 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2462,17 +2462,16 @@
     ]
   }
 
-  if (is_chromecast) {
-    deps += [ "//chromecast:chromecast_buildflags" ]
-  }
-
-  if (is_chromecast && (is_linux || is_chromeos)) {
+  if (is_castos) {
     sources += [
       "tracing/cast_tracing_agent.cc",
       "tracing/cast_tracing_agent.h",
     ]
 
-    deps += [ "//chromecast/tracing:system_tracer" ]
+    deps += [
+      "//chromecast:chromecast_buildflags",
+      "//chromecast/tracing:system_tracer",
+    ]
 
     defines += [ "CAST_TRACING_AGENT=1" ]
   }
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 37cb5163..ec9a17ec 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -563,13 +563,24 @@
     return;
   if (!ShouldFireEventForNode(node))
     return;
-  // Suppress events when |IGNORED_CHANGED| except for MenuClosed / MenuOpen
-  // since a change in the ignored state may show / hide a popup by exposing
-  // it to the tree or not.
+
+  // Suppress most events when the node just became ignored/unignored.
   if (IsIgnoredChangedNode(node)) {
     switch (uia_event) {
+      case UIA_LiveRegionChangedEventId:
+        // Don't suppress live region changed events on nodes that just became
+        // unignored, but suppress them on nodes that just became ignored. This
+        // ensures that ATs can announce LiveRegionChanged events on nodes that
+        // just appeared in the tree and not announce the ones that just got
+        // removed.
+        if (node->IsIgnored())
+          return;
+        break;
       case UIA_MenuClosedEventId:
       case UIA_MenuOpenedEventId:
+        // Don't suppress MenuClosed/MenuOpened events since a change in the
+        // ignored state may hide/show a popup by exposing it to the tree or
+        // not.
         break;
       default:
         return;
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
index a17b8f37..2cce0d5 100644
--- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
+++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -1470,12 +1470,12 @@
     ASSERT_NE(nullptr, popup_area);
     EXPECT_EQ(ax::mojom::Role::kRootWebArea, popup_area->GetRole());
 
-#if !BUILDFLAG(IS_CHROMECAST)
+#if !BUILDFLAG(IS_CASTOS) && !BUILDFLAG(IS_CAST_ANDROID)
     // Ensure that the bounding box of the popup area is at least 100
     // pixels down the page.
     gfx::Rect popup_bounds = popup_area->GetUnclippedRootFrameBoundsRect();
     EXPECT_GT(popup_bounds.y(), 100);
-#endif
+#endif  // !BUILDFLAG(IS_CASTOS) && !BUILDFLAG(IS_CAST_ANDROID)
   }
 }
 
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index e74e9dab..7233209 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -791,6 +791,13 @@
   RunEventTest(FILE_PATH_LITERAL("live-region-remove.html"));
 }
 
+IN_PROC_BROWSER_TEST_P(
+    DumpAccessibilityEventsTest,
+    AccessibilityEventsLiveRegionChangeOnFreshlyUnignoredNode) {
+  RunEventTest(
+      FILE_PATH_LITERAL("live-region-change-on-freshly-unignored-node.html"));
+}
+
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
                        AccessibilityEventsMenuListCollapse) {
   RunEventTest(FILE_PATH_LITERAL("menulist-collapse.html"));
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc
index 5193d191..5188abc 100644
--- a/content/browser/accessibility/hit_testing_browsertest.cc
+++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -804,7 +804,7 @@
 
 // GetAXPlatformNode is currently only supported on windows and linux (excluding
 // Chrome OS or Chromecast)
-#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMECAST))
+#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS))
 IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest,
                        NearestLeafInIframes) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/back_forward_cache_no_store_browsertest.cc b/content/browser/back_forward_cache_no_store_browsertest.cc
index fff73c892..edde07e 100644
--- a/content/browser/back_forward_cache_no_store_browsertest.cc
+++ b/content/browser/back_forward_cache_no_store_browsertest.cc
@@ -110,13 +110,13 @@
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // but does not get restored and gets evicted.
 // Turned off on cast for https://crbug.com/1281665 , along with others.
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreEnterBfcacheAndEvicted \
         DISABLED_PagesWithCacheControlNoStoreEnterBfcacheAndEvicted
 #else
 #define MAYBE_PagesWithCacheControlNoStoreEnterBfcacheAndEvicted \
         PagesWithCacheControlNoStoreEnterBfcacheAndEvicted
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestAllowCacheControlNoStore,
                        MAYBE_PagesWithCacheControlNoStoreEnterBfcacheAndEvicted) {
   net::test_server::ControllableHttpResponse response(embedded_test_server(),
@@ -163,13 +163,13 @@
 // and if a cookie is modified while it is in bfcache via JavaScript, gets
 // evicted with cookie modified marked.
 // Turned off on cast for https://crbug.com/1281665 .
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScript \
         DISABLED_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScript
 #else
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScript \
         PagesWithCacheControlNoStoreCookieModifiedThroughJavaScript
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(
     BackForwardCacheBrowserTestAllowCacheControlNoStore,
     MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScript) {
@@ -230,14 +230,16 @@
                   BlockListedFeatures()));
 }
 
-// Disabled due to flakiness on Cast Audio Linux https://crbug.com/1229182
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Audio Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedBackTwice \
   DISABLED_PagesWithCacheControlNoStoreCookieModifiedBackTwice
 #else
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedBackTwice \
   PagesWithCacheControlNoStoreCookieModifiedBackTwice
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and if a cookie is modified, it gets evicted with cookie changed, but if
 // navigated away again and navigated back, it gets evicted without cookie
@@ -304,18 +306,21 @@
                   BlockListedFeatures()));
 }
 
-// Flaky on Cast Audio Linux https://crbug.com/1229182
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and even if a cookie is modified on a different domain than the entry, the
 // entry is not marked as cookie modified.
 // Turned off on cast for https://crbug.com/1281665 .
-#if BUILDFLAG(IS_CHROMECAST)
+//
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Audio Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScriptOnDifferentDomain \
         DISABLED_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScriptOnDifferentDomain
 #else
 #define MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScriptOnDifferentDomain \
         PagesWithCacheControlNoStoreCookieModifiedThroughJavaScriptOnDifferentDomain
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(
     BackForwardCacheBrowserTestAllowCacheControlNoStore,
     MAYBE_PagesWithCacheControlNoStoreCookieModifiedThroughJavaScriptOnDifferentDomain) {
@@ -513,14 +518,16 @@
     "The server speaks HTTP!";
 }  // namespace
 
-// Disabled due to flakiness on Cast Audio Linux https://crbug.com/1229182
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Audio Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreSetFromResponseHeader \
   DISABLED_PagesWithCacheControlNoStoreSetFromResponseHeader
 #else
 #define MAYBE_PagesWithCacheControlNoStoreSetFromResponseHeader \
   PagesWithCacheControlNoStoreSetFromResponseHeader
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and if a cookie is modified while it is in bfcache via response header, gets
 // evicted with cookie modified marked.
@@ -581,14 +588,16 @@
                   BlockListedFeatures()));
 }
 
-// Disabled due to flakiness on Cast Audio Linux https://crbug.com/1229182
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Audio Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreSetFromResponseHeaderHTTPOnlyCookie \
   DISABLED_PagesWithCacheControlNoStoreSetFromResponseHeaderHTTPOnlyCookie
 #else
 #define MAYBE_PagesWithCacheControlNoStoreSetFromResponseHeaderHTTPOnlyCookie \
   PagesWithCacheControlNoStoreSetFromResponseHeaderHTTPOnlyCookie
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and if HTTPOnly cookie is modified while it is in bfcache, gets evicted with
 // HTTPOnly cookie modified marked.
@@ -655,14 +664,16 @@
           BlockListedFeatures()));
 }
 
-// Disabled due to flakiness on Cast Audio Linux https://crbug.com/1229182
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Audio Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreHTTPOnlyCookieModifiedBackTwice \
   DISABLED_PagesWithCacheControlNoStoreHTTPOnlyCookieModifiedBackTwice
 #else
 #define MAYBE_PagesWithCacheControlNoStoreHTTPOnlyCookieModifiedBackTwice \
   PagesWithCacheControlNoStoreHTTPOnlyCookieModifiedBackTwice
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and if a HTTPOnly cookie is modified, it gets evicted with cookie changed,
 // but if navigated away again and navigated back, it gets evicted without
@@ -763,16 +774,19 @@
   }
 };
 
-// TODO(https://crbug.com/1231849): flaky on Cast Linux.
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // and gets restored if cookies do not change.
-#if BUILDFLAG(IS_CHROMECAST)
+//
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast Linux.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreRestoreFromBackForwardCache \
   DISABLED_PagesWithCacheControlNoStoreRestoreFromBackForwardCache
 #else
 #define MAYBE_PagesWithCacheControlNoStoreRestoreFromBackForwardCache \
   PagesWithCacheControlNoStoreRestoreFromBackForwardCache
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(
     BackForwardCacheBrowserTestRestoreCacheControlNoStoreUnlessCookieChange,
     MAYBE_PagesWithCacheControlNoStoreRestoreFromBackForwardCache) {
@@ -803,17 +817,20 @@
   ExpectRestored(FROM_HERE);
 }
 
-// Flaky on Cast: crbug.com/1229182
 // Test that a page with cache-control:no-store enters bfcache with the flag on,
 // but gets evicted if cookies change.
 // Turned off on cast for https://crbug.com/1281665 .
-#if BUILDFLAG(IS_CHROMECAST)
+//
+// TODO(crbug.com/1336055): It may be possible to re-enable this test now that
+// crbug.com/1229182 has been resolved. This was originally disabled due to
+// flakiness on Cast.
+#if BUILDFLAG(IS_CASTOS)
 #define MAYBE_PagesWithCacheControlNoStoreEvictedIfCookieChange \
         DISABLED_PagesWithCacheControlNoStoreEvictedIfCookieChange
 #else
 #define MAYBE_PagesWithCacheControlNoStoreEvictedIfCookieChange \
         PagesWithCacheControlNoStoreEvictedIfCookieChange
-#endif
+#endif  // BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(
     BackForwardCacheBrowserTestRestoreCacheControlNoStoreUnlessCookieChange,
     MAYBE_PagesWithCacheControlNoStoreEvictedIfCookieChange) {
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index 4d7679c..b791cf4a 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -618,8 +618,8 @@
 template <typename Interface>
 void EmptyBinderForFrame(RenderFrameHost* host,
                          mojo::PendingReceiver<Interface> receiver) {
-  DLOG(ERROR) << "Empty binder for interface " << Interface::Name_
-              << " for the frame/document scope";
+  DVLOG(1) << "Empty binder for interface " << Interface::Name_
+           << " for the frame/document scope";
 }
 
 BatteryMonitorBinder& GetBatteryMonitorBinderOverride() {
diff --git a/content/browser/fenced_frame/fenced_frame_url_mapping.cc b/content/browser/fenced_frame/fenced_frame_url_mapping.cc
index 9f369e69..5bf52166 100644
--- a/content/browser/fenced_frame/fenced_frame_url_mapping.cc
+++ b/content/browser/fenced_frame/fenced_frame_url_mapping.cc
@@ -63,6 +63,20 @@
 
 }  // namespace
 
+FencedFrameURLMapping::SharedStorageURNMappingResult::
+    SharedStorageURNMappingResult() = default;
+
+FencedFrameURLMapping::SharedStorageURNMappingResult::
+    SharedStorageURNMappingResult(GURL mapped_url,
+                                  SharedStorageBudgetMetadata budget_metadata,
+                                  SharedStorageReportingMap reporting_map)
+    : mapped_url(std::move(mapped_url)),
+      budget_metadata(std::move(budget_metadata)),
+      reporting_map(std::move(reporting_map)) {}
+
+FencedFrameURLMapping::SharedStorageURNMappingResult::
+    ~SharedStorageURNMappingResult() = default;
+
 FencedFrameURLMapping::PendingAdComponentsMap::PendingAdComponentsMap(
     PendingAdComponentsMap&&) = default;
 
@@ -119,9 +133,11 @@
 
 FencedFrameURLMapping::MapInfo::MapInfo(
     const GURL& mapped_url,
-    const SharedStorageBudgetMetadata& shared_storage_budget_metadata)
+    const SharedStorageBudgetMetadata& shared_storage_budget_metadata,
+    const ReportingMetadata& reporting_metadata)
     : mapped_url(mapped_url),
-      shared_storage_budget_metadata(shared_storage_budget_metadata) {}
+      shared_storage_budget_metadata(shared_storage_budget_metadata),
+      reporting_metadata(reporting_metadata) {}
 
 FencedFrameURLMapping::MapInfo::MapInfo(const MapInfo&) = default;
 FencedFrameURLMapping::MapInfo::MapInfo(MapInfo&&) = default;
@@ -229,6 +245,7 @@
   DCHECK(!IsMapped(urn_uuid));
 
   absl::optional<GURL> mapped_url = absl::nullopt;
+  ReportingMetadata reporting_metadata;
 
   // Only if the resolved URL is fenced-frame-compatible do we:
   //   1.) Add it to `urn_uuid_to_url_map_`
@@ -236,19 +253,27 @@
   // TODO(crbug.com/1318970): Simplify this by making Shared Storage only
   // capable of producing URLs that fenced frames can navigate to.
   if (blink::IsValidFencedFrameURL(mapping_result.mapped_url)) {
+    base::flat_map<blink::mojom::ReportingDestination,
+                   SharedStorageReportingMap>
+        reporting_metadata_map;
+    reporting_metadata_map
+        [blink::mojom::ReportingDestination::kSharedStorageSelectUrl] =
+            std::move(mapping_result.reporting_map);
+    reporting_metadata = ReportingMetadata(std::move(reporting_metadata_map));
+
     urn_uuid_to_url_map_.emplace(
-        urn_uuid, MapInfo(mapping_result.mapped_url, mapping_result.metadata));
+        urn_uuid, MapInfo(mapping_result.mapped_url,
+                          mapping_result.budget_metadata, reporting_metadata));
     mapped_url = mapping_result.mapped_url;
   }
 
   std::set<raw_ptr<MappingResultObserver>>& observers = it->second;
 
-  ReportingMetadata metadata;
   for (raw_ptr<MappingResultObserver> observer : observers) {
     observer->OnFencedFrameURLMappingComplete(
         mapped_url, /*ad_auction_data=*/absl::nullopt,
         /*pending_ad_components_map=*/absl::nullopt,
-        /*reporting_metadata=*/metadata);
+        /*reporting_metadata=*/reporting_metadata);
   }
 
   pending_urn_uuid_to_url_map_.erase(it);
@@ -297,6 +322,24 @@
          pending_urn_uuid_to_url_map_.at(urn_uuid).count(observer);
 }
 
+void FencedFrameURLMapping::GetSharedStorageReportingMapForTesting(
+    const GURL& urn_uuid,
+    SharedStorageReportingMap* out_reporting_map) {
+  DCHECK(out_reporting_map);
+
+  auto urn_it = urn_uuid_to_url_map_.find(urn_uuid);
+  DCHECK(urn_it != urn_uuid_to_url_map_.end());
+
+  if (urn_it->second.reporting_metadata.metadata.empty())
+    return;
+
+  auto data_it = urn_it->second.reporting_metadata.metadata.find(
+      blink::mojom::ReportingDestination::kSharedStorageSelectUrl);
+
+  if (data_it != urn_it->second.reporting_metadata.metadata.end())
+    *out_reporting_map = data_it->second;
+}
+
 bool FencedFrameURLMapping::IsMapped(const GURL& urn_uuid) const {
   return urn_uuid_to_url_map_.find(urn_uuid) != urn_uuid_to_url_map_.end();
 }
diff --git a/content/browser/fenced_frame/fenced_frame_url_mapping.h b/content/browser/fenced_frame/fenced_frame_url_mapping.h
index ee92cc8..0704990 100644
--- a/content/browser/fenced_frame/fenced_frame_url_mapping.h
+++ b/content/browser/fenced_frame/fenced_frame_url_mapping.h
@@ -28,6 +28,7 @@
 };
 
 using ReportingMetadata = blink::mojom::FencedFrameReporting;
+using SharedStorageReportingMap = base::flat_map<std::string, ::GURL>;
 
 // Keeps a mapping of fenced frames URN:UUID and URL. Also keeps a set of
 // pending mapped URN:UUIDs to support asynchronous mapping. See
@@ -49,7 +50,13 @@
   // url and the `SharedStorageBudgetMetadata`.
   struct CONTENT_EXPORT SharedStorageURNMappingResult {
     GURL mapped_url;
-    SharedStorageBudgetMetadata metadata;
+    SharedStorageBudgetMetadata budget_metadata;
+    SharedStorageReportingMap reporting_map;
+    SharedStorageURNMappingResult();
+    SharedStorageURNMappingResult(GURL mapped_url,
+                                  SharedStorageBudgetMetadata budget_metadata,
+                                  SharedStorageReportingMap reporting_map);
+    ~SharedStorageURNMappingResult();
   };
 
   // When the result of an ad auction is a main ad URL with a set of ad
@@ -215,6 +222,16 @@
   bool HasObserverForTesting(const GURL& urn_uuid,
                              MappingResultObserver* observer);
 
+  // Returns as an out parameter the `ReportingMetadata`'s map for value
+  // `"shared-storage-select-url"` associated with `urn_uuid`, or leaves the out
+  // parameter unchanged if there's no shared storage reporting metadata
+  // associated (i.e. `urn_uuid` did not originate from shared storage or else
+  // there was no metadata passed from JavaScript). Precondition: `urn_uuid`
+  // exists in `urn_uuid_to_url_map_`.
+  void GetSharedStorageReportingMapForTesting(
+      const GURL& urn_uuid,
+      SharedStorageReportingMap* out_reporting_map);
+
  private:
   // Contains the URL a particular URN is mapped to, along with any extra data
   // associated with the URL that needs to be used on commit.
@@ -225,7 +242,8 @@
     MapInfo();
     explicit MapInfo(const GURL& url);
     MapInfo(const GURL& url,
-            const SharedStorageBudgetMetadata& shared_storage_budget_metadata);
+            const SharedStorageBudgetMetadata& shared_storage_budget_metadata,
+            const ReportingMetadata& reporting_metadata = ReportingMetadata());
     MapInfo(const MapInfo&);
     MapInfo(MapInfo&&);
     ~MapInfo();
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 260a2d4..88b4436 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -91,9 +91,9 @@
 #include "ui/display/win/screen_win.h"
 #include "ui/gfx/mojom/dxgi_info.mojom.h"
 #endif  // BUILDFLAG(IS_WIN)
-#if BUILDFLAG(IS_CHROMECAST)
-#include "chromecast/chromecast_buildflags.h"
-#endif
+#if BUILDFLAG(IS_CASTOS)
+#include "chromecast/chromecast_buildflags.h"  // nogncheck
+#endif                                         // BUILDFLAG(IS_CASTOS)
 
 namespace content {
 
@@ -633,14 +633,17 @@
   if (command_line->HasSwitch(switches::kDisableGpu)) {
     // Chomecast audio-only builds run with the flag --disable-gpu. The GPU
     // process should not access hardware GPU in this case.
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS)
 #if BUILDFLAG(IS_CAST_AUDIO_ONLY)
     fallback_modes_.clear();
     fallback_modes_.push_back(gpu::GpuMode::DISPLAY_COMPOSITOR);
-#endif
-#elif BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // BUILDFLAG(IS_CAST_AUDIO_ONLY)
+#endif  // BUILDFLAG(IS_CASTOS)
+
+#if (BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CAST_ANDROID)) || \
+    BUILDFLAG(IS_CHROMEOS_ASH)
     CHECK(false) << "GPU acceleration is required on certain platforms!";
-#endif  // IS_CHROMECAST
+#endif
   } else {
     // On Fuchsia Vulkan must be used when it's enabled by the WebEngine
     // embedder. Falling back to SW compositing in that case is not supported.
diff --git a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
index 761e6be..1285dd6 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -26,12 +26,14 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-#if BUILDFLAG(IS_CHROMECAST)
-#include "chromecast/chromecast_buildflags.h"
+// TODO(crbug.com/1293538): The IS_CAST_AUDIO_ONLY check should not need to be
+// nested inside of an IS_CASTOS check.
+#if BUILDFLAG(IS_CASTOS)
+#include "chromecast/chromecast_buildflags.h"  // nogncheck
 #if BUILDFLAG(IS_CAST_AUDIO_ONLY)
 #define CAST_AUDIO_ONLY
-#endif
-#endif
+#endif  // BUILDFLAG(IS_CAST_AUDIO_ONLY)
+#endif  // BUILDFLAG(IS_CASTOS)
 
 namespace content {
 namespace {
@@ -320,7 +322,7 @@
   ScopedGpuDataManagerImplPrivate manager;
   EXPECT_EQ(gpu::GpuMode::DISPLAY_COMPOSITOR, manager->GetGpuMode());
 }
-#endif  // IS_CHROMECAST
+#endif  // defined(CAST_AUDIO_ONLY)
 
 #if BUILDFLAG(IS_MAC)
 TEST_F(GpuDataManagerImplPrivateTest, FallbackFromMetalToGL) {
diff --git a/content/browser/media/media_color_browsertest.cc b/content/browser/media/media_color_browsertest.cc
index c14d57e..6475809 100644
--- a/content/browser/media/media_color_browsertest.cc
+++ b/content/browser/media/media_color_browsertest.cc
@@ -42,24 +42,55 @@
 
 // Android doesn't support Theora.
 #if !BUILDFLAG(IS_ANDROID)
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv420pTheora) {
+
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv420pTheora DISABLED_Yuv420pTheora
+#else
+#define MAYBE_Yuv420pTheora Yuv420pTheora
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv420pTheora) {
   RunColorTest("yuv420p.ogv");
 }
 
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv422pTheora) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv422pTheora DISABLED_Yuv422pTheora
+#else
+#define MAYBE_Yuv422pTheora Yuv422pTheora
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv422pTheora) {
   RunColorTest("yuv422p.ogv");
 }
 
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv444pTheora) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv444pTheora DISABLED_Yuv444pTheora
+#else
+#define MAYBE_Yuv444pTheora Yuv444pTheora
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv444pTheora) {
   RunColorTest("yuv444p.ogv");
 }
 #endif  // !BUILDFLAG(IS_ANDROID)
 
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv420pVp8) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv420pVp8 DISABLED_Yuv420pVp8
+#else
+#define MAYBE_Yuv420pVp8 Yuv420pVp8
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv420pVp8) {
   RunColorTest("yuv420p.webm");
 }
 
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv444pVp9) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv444pVp9 DISABLED_Yuv444pVp9
+#else
+#define MAYBE_Yuv444pVp9 Yuv444pVp9
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv444pVp9) {
   RunColorTest("yuv444p.webm");
 }
 
@@ -67,7 +98,8 @@
 
 // This test fails on Android: http://crbug.com/938320
 // It also fails on ChromeOS https://crbug.com/938618
-#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
 #define MAYBE_Yuv420pH264 DISABLED_Yuv420pH264
 #else
 #define MAYBE_Yuv420pH264 Yuv420pH264
@@ -85,7 +117,8 @@
 }
 
 // This test fails on Android: http://crbug.com/647818
-#if BUILDFLAG(IS_ANDROID)
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
 #define MAYBE_Yuvj420pH264 DISABLED_Yuvj420pH264
 #else
 #define MAYBE_Yuvj420pH264 Yuvj420pH264
@@ -96,7 +129,8 @@
 
 // This fails on ChromeOS: http://crbug.com/647400,
 // This fails on Android: http://crbug.com/938320,
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID)
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
 #define MAYBE_Yuv420pRec709H264 DISABLED_Yuv420pRec709H264
 #else
 #define MAYBE_Yuv420pRec709H264 Yuv420pRec709H264
@@ -126,11 +160,23 @@
 
 // Android devices usually only support baseline, main and high.
 #if !BUILDFLAG(IS_ANDROID)
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv422pH264) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv422pH264 DISABLED_Yuv422pH264
+#else
+#define MAYBE_Yuv422pH264 Yuv422pH264
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv422pH264) {
   RunColorTest("yuv422p.mp4");
 }
 
-IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv444pH264) {
+// See https://crbug.com/1336588; several Yuv* tests are flaky on Mac.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_Yuv444pH264 DISABLED_Yuv444pH264
+#else
+#define MAYBE_Yuv444pH264 Yuv444pH264
+#endif
+IN_PROC_BROWSER_TEST_F(MediaColorTest, MAYBE_Yuv444pH264) {
   RunColorTest("yuv444p.mp4");
 }
 #endif  // !BUILDFLAG(IS_ANDROID)
diff --git a/content/browser/message_port_provider.cc b/content/browser/message_port_provider.cc
index a46b8700..1e9ab138 100644
--- a/content/browser/message_port_provider.cc
+++ b/content/browser/message_port_provider.cc
@@ -87,7 +87,12 @@
 }
 #endif
 
-#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1329657): The last IS_FUCHSIA check will not be needed once
+// its build sets enable_cast_receiver.
+#if BUILDFLAG(ENABLE_CAST_RECEIVER) &&                    \
+        (BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CASTOS) || \
+         BUILDFLAG(IS_CAST_ANDROID)) ||                   \
+    BUILDFLAG(IS_FUCHSIA)
 // static
 void MessagePortProvider::PostMessageToFrame(
     Page& page,
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index d07aee7..8850a34c 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
+#include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
@@ -6087,4 +6088,62 @@
             second_tab_handle->GetRedirectChain());
 }
 
+class CacheTransparencyNavigationBrowserTest : public ContentBrowserTest {
+ public:
+  CacheTransparencyNavigationBrowserTest() {
+    EXPECT_TRUE(embedded_test_server()->Start());
+
+    pervasive_payload_url_ = embedded_test_server()->GetURL(kPervasivePayload);
+    std::string pervasive_payloads_params = base::StrCat(
+        {"1,", pervasive_payload_url_.spec(),
+         ",87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"});
+
+    feature_list_.InitWithFeaturesAndParameters(
+        {{features::kNetworkServiceInProcess, {}},
+         {network::features::kPervasivePayloadsList,
+          {{"pervasive-payloads", pervasive_payloads_params}}},
+         {network::features::kCacheTransparency, {}},
+         {net::features::kSplitCacheByNetworkIsolationKey, {}}},
+        {/* disabled_features */});
+  }
+
+  void ExpectCacheUsed() const {
+    histogram_tester_.ExpectUniqueSample(kCacheUsedHistogram, 0, 1);
+  }
+
+  void ExpectCacheNotUsed() const {
+    histogram_tester_.ExpectTotalCount(kCacheUsedHistogram, 0);
+  }
+
+ private:
+  static constexpr char kPervasivePayload[] =
+      "/cache_transparency/pervasive.js";
+  static constexpr char kCacheUsedHistogram[] =
+      "Network.CacheTransparency.SingleKeyedCacheIsUsed";
+
+  base::test::ScopedFeatureList feature_list_;
+  GURL pervasive_payload_url_;
+  base::HistogramTester histogram_tester_;
+};
+
+IN_PROC_BROWSER_TEST_F(CacheTransparencyNavigationBrowserTest,
+                       SuccessfulPervasivePayload) {
+  GURL url_main_document =
+      embedded_test_server()->GetURL("/cache_transparency/pervasive.html");
+
+  EXPECT_TRUE(NavigateToURL(shell(), url_main_document));
+
+  ExpectCacheUsed();
+}
+
+IN_PROC_BROWSER_TEST_F(CacheTransparencyNavigationBrowserTest,
+                       NotAPervasivePayload) {
+  GURL url_main_document =
+      embedded_test_server()->GetURL("/cache_transparency/cacheable.html");
+
+  EXPECT_TRUE(NavigateToURL(shell(), url_main_document));
+
+  ExpectCacheNotUsed();
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/frame_tree_browsertest.cc b/content/browser/renderer_host/frame_tree_browsertest.cc
index 24cd1e2..4113b40 100644
--- a/content/browser/renderer_host/frame_tree_browsertest.cc
+++ b/content/browser/renderer_host/frame_tree_browsertest.cc
@@ -1074,7 +1074,7 @@
   GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url);
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
 
   {
     TestFrameNavigationObserver observer(fenced_frame_root_node);
@@ -1140,8 +1140,7 @@
   {
     TestFrameNavigationObserver observer(
         fenced_frame_root_node1->current_frame_host());
-    std::string navigate_urn_script =
-        JsReplace("f1.src = $1;", urn_uuid.spec());
+    std::string navigate_urn_script = JsReplace("f1.src = $1;", urn_uuid);
     EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script));
     observer.Wait();
   }
@@ -1149,8 +1148,7 @@
   {
     TestFrameNavigationObserver observer(
         fenced_frame_root_node2->current_frame_host());
-    std::string navigate_urn_script =
-        JsReplace("f2.src = $1;", urn_uuid.spec());
+    std::string navigate_urn_script = JsReplace("f2.src = $1;", urn_uuid);
     EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script));
     observer.Wait();
   }
@@ -1192,7 +1190,7 @@
   const GURL urn_uuid = url_mapping.GeneratePendingMappedURN();
   const GURL mapped_url =
       https_server()->GetURL("a.test", "/fenced_frames/title1.html");
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
 
   TestFrameNavigationObserver observer(
       fenced_frame_root_node->current_frame_host());
@@ -1270,7 +1268,7 @@
   const GURL urn_uuid = url_mapping.GeneratePendingMappedURN();
   const GURL mapped_url =
       https_server()->GetURL("a.test", "/fenced_frames/nonexistent-url.html");
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
 
   TestFrameNavigationObserver observer(
       fenced_frame_root_node->current_frame_host());
@@ -1338,7 +1336,7 @@
   const GURL urn_uuid = url_mapping.GeneratePendingMappedURN();
   const GURL mapped_url =
       https_server()->GetURL("a.test", "/fenced_frames/title1.html");
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
 
   TestFrameNavigationObserver observer(
       fenced_frame_root_node->current_frame_host());
@@ -1416,7 +1414,7 @@
   GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url);
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad(
       fenced_frame_root_node, urn_uuid, navigate_urn_script);
   EXPECT_EQ(
@@ -1498,7 +1496,7 @@
   GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url);
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad(
       fenced_frame_root_node, urn_uuid, navigate_urn_script);
   EXPECT_EQ(
@@ -1837,7 +1835,7 @@
   GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url);
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad(
       fenced_frame_root_node, urn_uuid, navigate_urn_script,
       net::ERR_BLOCKED_BY_RESPONSE);
@@ -2803,7 +2801,7 @@
   GURL urn_uuid = GURL("urn:uuid:12345678-9abc-def0-1234-56789abcdef0");
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad(
       fenced_frame_root_node, urn_uuid, navigate_urn_script, InvalidUrnError());
 }
@@ -2864,7 +2862,7 @@
     GURL urn_uuid = url_mapping.AddFencedFrameURL(https_url);
     EXPECT_TRUE(urn_uuid.is_valid());
 
-    std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+    std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
 
     net::Error expected_net_error_code =
         test_case.expect_allowed ? net::OK : net::ERR_BLOCKED_BY_CSP;
@@ -3341,6 +3339,14 @@
 
 class FencedFrameReportEventBrowserTest : public FencedFrameTreeBrowserTest {
  public:
+  // TODO(crbug.com/1123606): Disable window.fence.reportEvent in iframes.
+  // Remove this constructor and `scoped_feature_list_` once FLEDGE stops
+  // supporting iframes.
+  FencedFrameReportEventBrowserTest() {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{blink::features::kAllowURNsInIframes, {}}},
+        {/* disabled_features */});
+  }
   void SetUpOnMainThread() override {
     // Set up the host resolver to allow serving separate sites, so we can
     // perform cross-process navigation.
@@ -3354,6 +3360,9 @@
     https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
     https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
   }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Tests that the fenced frame with a urn:uuid commits the navigation with the
@@ -3400,12 +3409,13 @@
       url_mapping.AddFencedFrameURL(https_url, fenced_frame_reporting);
   EXPECT_TRUE(urn_uuid.is_valid());
 
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
-
   TestFencedFrameURLMappingResultObserver mapping_observer;
   url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &mapping_observer);
   TestFrameNavigationObserver observer(fenced_frame_root_node);
+
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   EXPECT_EQ(urn_uuid.spec(), EvalJs(root, navigate_urn_script));
+
   observer.WaitForCommit();
   EXPECT_TRUE(mapping_observer.mapping_complete_observed());
   EXPECT_EQ(reporting_url,
@@ -3432,6 +3442,77 @@
   EXPECT_EQ(response.http_request()->content, event_data);
 }
 
+// (Temporary test for FLEDGE iframe OT.)
+// Tests that an iframe with a urn:uuid commits the navigation with the
+// associated reporting metadata and `fence.reportEvent` sends the beacon to
+// the registered reporting url.
+// TODO(crbug.com/1123606): Disable window.fence.reportEvent in iframes.
+// Remove this test once the FLEDGE origin trial stops supporting iframes.
+IN_PROC_BROWSER_TEST_P(FencedFrameReportEventBrowserTest,
+                       IframeReportingMetadata) {
+  net::test_server::ControllableHttpResponse response(https_server(),
+                                                      "/title2.html");
+  ASSERT_TRUE(https_server()->Start());
+
+  GURL main_url = https_server()->GetURL("b.test", "/hello.html");
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+  // It is safe to obtain the root frame tree node here, as it doesn't change.
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_TRUE(ExecJs(root,
+                     "var f = document.createElement('iframe');"
+                     "document.body.appendChild(f);"));
+  EXPECT_EQ(1U, root->child_count());
+  FrameTreeNode* iframe_node = root->child_at(0);
+
+  // Add reporting metadata.
+  ReportingMetadata fenced_frame_reporting;
+  GURL reporting_url(https_server()->GetURL("c.test", "/title2.html"));
+  fenced_frame_reporting.metadata[blink::mojom::ReportingDestination::kBuyer]
+                                 ["mouse interaction"] = reporting_url;
+  fenced_frame_reporting
+      .metadata[blink::mojom::ReportingDestination::kBuyer]["click"] =
+      https_server()->GetURL("c.test", "/title1.html");
+
+  GURL https_url(
+      https_server()->GetURL("a.test", "/fenced_frames/title1.html"));
+  FencedFrameURLMapping& url_mapping =
+      root->current_frame_host()->GetPage().fenced_frame_urls_map();
+  GURL urn_uuid =
+      url_mapping.AddFencedFrameURL(https_url, fenced_frame_reporting);
+  EXPECT_TRUE(urn_uuid.is_valid());
+
+  TestFencedFrameURLMappingResultObserver mapping_observer;
+  url_mapping.ConvertFencedFrameURNToURL(urn_uuid, &mapping_observer);
+  TestFrameNavigationObserver observer(iframe_node);
+
+  EXPECT_EQ(urn_uuid.spec(), EvalJs(root, JsReplace("f.src = $1;", urn_uuid)));
+
+  observer.WaitForCommit();
+  EXPECT_TRUE(mapping_observer.mapping_complete_observed());
+  EXPECT_EQ(reporting_url,
+            mapping_observer.reporting_metadata()
+                .metadata[blink::mojom::ReportingDestination::kBuyer]
+                         ["mouse interaction"]);
+
+  EXPECT_EQ(https_url,
+            iframe_node->current_frame_host()->GetLastCommittedURL());
+  EXPECT_EQ(url::Origin::Create(https_url),
+            iframe_node->current_frame_host()->GetLastCommittedOrigin());
+
+  std::string event_data = "this is a click";
+  EXPECT_TRUE(ExecJs(iframe_node, JsReplace("window.fence.reportEvent({"
+                                            "  eventType: 'mouse interaction',"
+                                            "  eventData: $1,"
+                                            "  destination: ['buyer']});",
+                                            event_data)));
+
+  response.WaitForRequest();
+  EXPECT_EQ(response.http_request()->content, event_data);
+}
+
 IN_PROC_BROWSER_TEST_P(FencedFrameReportEventBrowserTest,
                        NestedIframeReportEvent) {
   net::test_server::ControllableHttpResponse response(https_server(),
@@ -3471,7 +3552,7 @@
   EXPECT_TRUE(urn_uuid.is_valid());
 
   // Navigate the fenced frame.
-  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid.spec());
+  std::string navigate_urn_script = JsReplace("f.src = $1;", urn_uuid);
   NavigateFrameInsideFencedFrameTreeAndWaitForFinishedLoad(
       fenced_frame_root_node, urn_uuid, navigate_urn_script);
 
diff --git a/content/browser/renderer_host/input/fling_controller_unittest.cc b/content/browser/renderer_host/input/fling_controller_unittest.cc
index 81208f00..af6836c 100644
--- a/content/browser/renderer_host/input/fling_controller_unittest.cc
+++ b/content/browser/renderer_host/input/fling_controller_unittest.cc
@@ -788,7 +788,7 @@
   // Android and Chromecast use Mobile fling curve so they are ignored
   // for this test
   bool use_mobile_fling_curve = false;
-#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CASTOS)
   use_mobile_fling_curve = true;
 #endif
   if (use_mobile_fling_curve)
@@ -835,7 +835,7 @@
   // Android and Chromecast use Mobile fling curve so they are ignored
   // for this test
   bool use_mobile_fling_curve = false;
-#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CASTOS)
   use_mobile_fling_curve = true;
 #endif
   if (use_mobile_fling_curve)
diff --git a/content/browser/renderer_host/render_frame_host.cc b/content/browser/renderer_host/render_frame_host.cc
index 1171fae..a6c4f43 100644
--- a/content/browser/renderer_host/render_frame_host.cc
+++ b/content/browser/renderer_host/render_frame_host.cc
@@ -8,5 +8,5 @@
 // impact on build time. Try not to raise this limit unless necessary. See
 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
 #ifndef NACL_TC_REV
-#pragma clang max_tokens_here 660000
+#pragma clang max_tokens_here 670000
 #endif
diff --git a/content/browser/service_process_host_impl.cc b/content/browser/service_process_host_impl.cc
index 4753726..627f45c 100644
--- a/content/browser/service_process_host_impl.cc
+++ b/content/browser/service_process_host_impl.cc
@@ -219,7 +219,11 @@
   }
 }
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 void LaunchUtilityProcessServiceDeprecated(
     const std::string& service_name,
     const std::u16string& display_name,
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc
index c751db76..b5f5773 100644
--- a/content/browser/shared_storage/shared_storage_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "content/browser/renderer_host/navigation_request.h"
@@ -27,6 +28,7 @@
 #include "content/test/content_browser_test_utils_internal.h"
 #include "content/test/fenced_frame_test_utils.h"
 #include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/controllable_http_response.h"
 #include "net/test/embedded_test_server/request_handler_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -35,6 +37,10 @@
 
 namespace content {
 
+using testing::Pair;
+using testing::UnorderedElementsAre;
+using SharedStorageReportingMap = base::flat_map<std::string, ::GURL>;
+
 namespace {
 
 const char kSimplePagePath[] = "/simple_page.html";
@@ -48,7 +54,10 @@
 const char kSelectFrom8URLsScript[] = R"(
     let urls = [];
     for (let i = 0; i < 8; ++i) {
-      urls.push('fenced_frames/title' + i.toString() + '.html');
+      urls.push({url: 'fenced_frames/title' + i.toString() + '.html',
+                 reporting_metadata: {
+                   'click': 'fenced_frames/report' + i.toString() + '.html'
+                 }});
     }
 
     sharedStorage.selectURL(
@@ -325,7 +334,12 @@
             std::move(test_worklet_host_manager));
 
     host_resolver()->AddRule("*", "127.0.0.1");
+    FinishSetup();
+  }
 
+  // Virtual so that derived classes can delay starting the server, and/or add
+  // other set up steps.
+  virtual void FinishSetup() {
     https_server()->AddDefaultHandlers(GetTestDataFilePath());
     https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
     SetupCrossSiteRedirector(https_server());
@@ -358,6 +372,22 @@
     return metadata;
   }
 
+  SharedStorageReportingMap GetSharedStorageReportingMap(const GURL& urn_uuid) {
+    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                              ->GetPrimaryFrameTree()
+                              .root();
+
+    FencedFrameURLMapping& fenced_frame_url_mapping =
+        root->current_frame_host()->GetPage().fenced_frame_urls_map();
+
+    SharedStorageReportingMap reporting_map;
+
+    fenced_frame_url_mapping.GetSharedStorageReportingMapForTesting(
+        GURL(urn_uuid), &reporting_map);
+
+    return reporting_map;
+  }
+
   void ExecuteScriptInWorklet(const ToRenderFrameHost& execution_target,
                               const std::string& script) {
     base::StringPairs run_function_body_replacement;
@@ -1012,7 +1042,7 @@
 // This specifically tests the operation success scenario.
 IN_PROC_BROWSER_TEST_F(
     SharedStorageBrowserTest,
-    RunURLSelectionOperation_BudgetMetadata_OperationSuccess_SingleInputURL) {
+    SelectURL_BudgetMetadata_OperationSuccess_SingleInputURL) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1025,7 +1055,10 @@
   std::string urn_uuid = EvalJs(shell(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html"], {data: {'mockResult':0}});
+          [{url: "fenced_frames/title0.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html",
+              "mouse interaction": "fenced_frames/report2.html"}}],
+          {data: {'mockResult':0}});
     )")
                              .ExtractString();
 
@@ -1042,6 +1075,14 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, 0.0);
 
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report1.html")),
+                  Pair("mouse interaction",
+                       https_server()->GetURL("a.test",
+                                              "/fenced_frames/report2.html"))));
+
   EXPECT_EQ("Finish executing 'test-url-selection-operation'",
             base::UTF16ToUTF8(console_observer.messages().back().message));
 }
@@ -1050,7 +1091,7 @@
 // This specifically tests the operation failure scenario.
 IN_PROC_BROWSER_TEST_F(
     SharedStorageBrowserTest,
-    RunURLSelectionOperation_BudgetMetadata_OperationFailure_SingleInputURL) {
+    SelectURL_BudgetMetadata_OperationFailure_SingleInputURL) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1063,7 +1104,9 @@
   std::string urn_uuid = EvalJs(shell(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html"], {data: {'mockResult':-1}});
+          [{url: "fenced_frames/title0.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}}],
+          {data: {'mockResult':-1}});
     )")
                              .ExtractString();
 
@@ -1080,13 +1123,18 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, 0.0);
 
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report1.html"))));
+
   EXPECT_EQ(
       "Promise resolved to a number outside the length of the input urls.",
       base::UTF16ToUTF8(console_observer.messages().back().message));
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
-                       RunURLSelectionOperation_BudgetMetadata_Origin) {
+                       SelectURL_BudgetMetadata_Origin) {
   EXPECT_TRUE(NavigateToURL(
       shell(), https_server()->GetURL("a.test", kPageWithBlankIframePath)));
 
@@ -1110,8 +1158,10 @@
   std::string urn_uuid = EvalJs(iframe, R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html", "fenced_frames/title1.html",
-          "fenced_frames/title2.html"], {data: {'mockResult': 1}});
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 1}});
     )")
                              .ExtractString();
 
@@ -1127,6 +1177,56 @@
   EXPECT_TRUE(metadata);
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("b.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, std::log2(3));
+
+  SharedStorageReportingMap reporting_map =
+      GetSharedStorageReportingMap(GURL(urn_uuid));
+  EXPECT_FALSE(reporting_map.empty());
+  EXPECT_EQ(1U, reporting_map.size());
+  EXPECT_EQ("click", reporting_map.begin()->first);
+  EXPECT_EQ(https_server()->GetURL("b.test", "/fenced_frames/report1.html"),
+            reporting_map.begin()->second);
+}
+
+IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
+                       SelectURL_ReportingMetadata_EmptyReportEvent) {
+  GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  WebContentsConsoleObserver console_observer(shell()->web_contents());
+
+  EXPECT_TRUE(ExecJs(shell(), R"(
+      sharedStorage.worklet.addModule('shared_storage/simple_module.js');
+    )"));
+
+  std::string urn_uuid = EvalJs(shell(), R"(
+      sharedStorage.selectURL(
+          'test-url-selection-operation',
+          [{url: "fenced_frames/title0.html",
+          reporting_metadata: {"": "fenced_frames/report1.html"}}],
+          {data: {'mockResult':0}});
+    )")
+                             .ExtractString();
+
+  EXPECT_TRUE(blink::IsValidUrnUuidURL(GURL(urn_uuid)));
+
+  // There are 2 "worklet operations": `addModule()` and `selectURL()`.
+  test_worklet_host_manager()
+      .GetAttachedWorkletHost()
+      ->WaitForWorkletResponsesCount(2);
+
+  FencedFrameURLMapping::SharedStorageBudgetMetadata* metadata =
+      GetSharedStorageBudgetMetadata(GURL(urn_uuid));
+  EXPECT_TRUE(metadata);
+  EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
+  EXPECT_DOUBLE_EQ(metadata->budget_to_charge, 0.0);
+
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("", https_server()->GetURL(
+                               "a.test", "/fenced_frames/report1.html"))));
+
+  EXPECT_EQ("Finish executing 'test-url-selection-operation'",
+            base::UTF16ToUTF8(console_observer.messages().back().message));
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, SetAppendOperationInDocument) {
@@ -1562,9 +1662,8 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_P(
-    SharedStorageFencedFrameInteractionBrowserTest,
-    RunURLSelectionOperation_FinishBeforeStartingFencedFrameNavigation) {
+IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
+                       SelectURL_FinishBeforeStartingFencedFrameNavigation) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1585,8 +1684,10 @@
   std::string urn_uuid = EvalJs(shell(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html", "fenced_frames/title1.html",
-          "fenced_frames/title2.html"], {data: {'mockResult': 1}});
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 1}});
     )")
                              .ExtractString();
 
@@ -1603,6 +1704,11 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, std::log2(3));
 
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report1.html"))));
+
   GURL url0 = https_server()->GetURL("a.test", "/fenced_frames/title0.html");
   GURL url1 = https_server()->GetURL("a.test", "/fenced_frames/title1.html");
   GURL url2 = https_server()->GetURL("a.test", "/fenced_frames/title2.html");
@@ -1647,7 +1753,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
-                       RunURLSelectionOperationNotAllowedInFencedFrame) {
+                       SelectURLNotAllowedInFencedFrame) {
   GURL main_frame_url = https_server()->GetURL("a.test", kSimplePagePath);
 
   EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
@@ -1667,16 +1773,15 @@
   EvalJsResult result = EvalJs(fenced_frame_node, R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["title0.html"], {data: {'mockResult': 0}});
+          [{url: "title0.html"}], {data: {'mockResult': 0}});
     )");
 
   EXPECT_TRUE(result.error.find("sharedStorage.selectURL() is not allowed in "
                                 "fenced frame") != std::string::npos);
 }
 
-IN_PROC_BROWSER_TEST_P(
-    SharedStorageFencedFrameInteractionBrowserTest,
-    RunURLSelectionOperation_FinishAfterStartingFencedFrameNavigation) {
+IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
+                       SelectURL_FinishAfterStartingFencedFrameNavigation) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1696,8 +1801,10 @@
   std::string urn_uuid = EvalJs(shell(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html", "fenced_frames/title1.html",
-          "fenced_frames/title2.html"], {data: {'mockResult': 1}});
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 1}});
     )")
                              .ExtractString();
 
@@ -1761,15 +1868,20 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, std::log2(3));
 
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report1.html"))));
+
   EXPECT_EQ(
       https_server()->GetURL("a.test", "/fenced_frames/title1.html"),
       fenced_frame_root_node->current_frame_host()->GetLastCommittedURL());
 }
 
-// Tests that the URN from RunURLSelectionOperation() is valid in different
+// Tests that the URN from SelectURL() is valid in different
 // context in the page, but it's not valid in a new page.
 IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
-                       RunURLSelectionOperation_URNLifetime) {
+                       SelectURL_URNLifetime) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1807,9 +1919,8 @@
 
 // Tests that if the URN mapping is not finished before the keep-alive timeout,
 // the mapping will be considered to be failed when the timeout is reached.
-IN_PROC_BROWSER_TEST_P(
-    SharedStorageFencedFrameInteractionBrowserTest,
-    RunURLSelectionOperation_NotFinishBeforeKeepAliveTimeout) {
+IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
+                       SelectURL_NotFinishBeforeKeepAliveTimeout) {
   // The test assumes pages get deleted after navigation. To ensure this,
   // disable back/forward cache.
   content::DisableBackForwardCacheForTesting(
@@ -1905,13 +2016,18 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, 0.0);
 
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report0.html"))));
+
   EXPECT_EQ(
       https_server()->GetURL("a.test", "/fenced_frames/title0.html"),
       fenced_frame_root_node->current_frame_host()->GetLastCommittedURL());
 }
 
 IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
-                       RunURLSelectionOperation_WorkletReturnInvalidIndex) {
+                       SelectURL_WorkletReturnInvalidIndex) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -1927,8 +2043,10 @@
   std::string urn_uuid = EvalJs(shell(), R"(
       sharedStorage.selectURL(
           'test-url-selection-operation',
-          ["fenced_frames/title0.html", "fenced_frames/title1.html",
-          "fenced_frames/title2.html"], {data: {'mockResult': 3}});
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 3}});
     )")
                              .ExtractString();
 
@@ -1949,6 +2067,8 @@
   EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
   EXPECT_DOUBLE_EQ(metadata->budget_to_charge, 1.0);
 
+  EXPECT_TRUE(GetSharedStorageReportingMap(GURL(urn_uuid)).empty());
+
   FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                             ->GetPrimaryFrameTree()
                             .root();
@@ -1978,6 +2098,80 @@
 }
 
 IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
+                       SelectURL_DuplicateUrl) {
+  GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  WebContentsConsoleObserver console_observer(shell()->web_contents());
+
+  EXPECT_TRUE(ExecJs(shell(), R"(
+      sharedStorage.worklet.addModule('shared_storage/simple_module.js');
+    )"));
+
+  EXPECT_EQ(1u, test_worklet_host_manager().GetAttachedWorkletHostsCount());
+  EXPECT_EQ(0u, test_worklet_host_manager().GetKeepAliveWorkletHostsCount());
+
+  std::string urn_uuid = EvalJs(shell(), R"(
+      sharedStorage.selectURL(
+          'test-url-selection-operation',
+          [{url: "fenced_frames/title.html"},
+          {url: "fenced_frames/title0.html",
+          url: "fenced_frames/title1.html",
+          reporting_metadata: {"click": "fenced_frames/report1.html"}},
+          {url: "fenced_frames/title2.html"}], {data: {'mockResult': 1}});
+    )")
+                             .ExtractString();
+
+  EXPECT_TRUE(blink::IsValidUrnUuidURL(GURL(urn_uuid)));
+
+  // There are 2 "worklet operations": `addModule()` and `selectURL()`.
+  test_worklet_host_manager()
+      .GetAttachedWorkletHost()
+      ->WaitForWorkletResponsesCount(2);
+
+  EXPECT_EQ("Finish executing 'test-url-selection-operation'",
+            base::UTF16ToUTF8(console_observer.messages().back().message));
+
+  FencedFrameURLMapping::SharedStorageBudgetMetadata* metadata =
+      GetSharedStorageBudgetMetadata(GURL(urn_uuid));
+  EXPECT_TRUE(metadata);
+  EXPECT_EQ(metadata->origin, https_server()->GetOrigin("a.test"));
+  EXPECT_DOUBLE_EQ(metadata->budget_to_charge, std::log2(3));
+
+  EXPECT_THAT(GetSharedStorageReportingMap(GURL(urn_uuid)),
+              UnorderedElementsAre(
+                  Pair("click", https_server()->GetURL(
+                                    "a.test", "/fenced_frames/report1.html"))));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetPrimaryFrameTree()
+                            .root();
+
+  EXPECT_TRUE(ExecJs(root,
+                     "var f = document.createElement('fencedframe');"
+                     "f.mode = 'opaque-ads';"
+                     "document.body.appendChild(f);"));
+
+  EXPECT_EQ(1U, root->child_count());
+  FrameTreeNode* fenced_frame_root_node =
+      GetFencedFrameRootNode(root->child_at(0));
+
+  std::string navigate_fenced_frame_to_urn_script =
+      JsReplace("f.src = $1;", urn_uuid);
+
+  TestFrameNavigationObserver observer(
+      fenced_frame_root_node->current_frame_host());
+
+  EXPECT_EQ(urn_uuid, EvalJs(root, navigate_fenced_frame_to_urn_script));
+
+  observer.Wait();
+
+  EXPECT_EQ(
+      https_server()->GetURL("a.test", "/fenced_frames/title1.html"),
+      fenced_frame_root_node->current_frame_host()->GetLastCommittedURL());
+}
+
+IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
                        FencedFrameNavigateSelf_NoBudgetWithdrawal) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -2328,7 +2522,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(SharedStorageFencedFrameInteractionBrowserTest,
-                       RunURLSelectionOperation_InsufficientBudget) {
+                       SelectURL_InsufficientBudget) {
   GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
@@ -2380,4 +2574,81 @@
         blink::features::FencedFramesImplementationType::kMPArch),
     &SharedStorageFencedFrameInteractionBrowserTest::DescribeParams);
 
+class SharedStorageReportEventBrowserTest
+    : public SharedStorageFencedFrameInteractionBrowserTest {
+  void FinishSetup() override {
+    https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
+    https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+  }
+};
+
+IN_PROC_BROWSER_TEST_P(SharedStorageReportEventBrowserTest,
+                       SelectURL_ReportEvent) {
+  net::test_server::ControllableHttpResponse response1(
+      https_server(), "/fenced_frames/report1.html");
+  net::test_server::ControllableHttpResponse response2(
+      https_server(), "/fenced_frames/report2.html");
+  ASSERT_TRUE(https_server()->Start());
+
+  GURL main_url = https_server()->GetURL("a.test", kSimplePagePath);
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  url::Origin shared_storage_origin = url::Origin::Create(main_url);
+
+  EXPECT_TRUE(ExecJs(shell(), R"(
+      sharedStorage.worklet.addModule('shared_storage/simple_module.js');
+    )"));
+
+  GURL urn_uuid = GURL(EvalJs(shell(), R"(
+      sharedStorage.selectURL(
+          'test-url-selection-operation',
+          [{url: "fenced_frames/title0.html"},
+          {url: "fenced_frames/title1.html",
+          reporting_metadata: {'click': "fenced_frames/report1.html",
+              'mouse interaction': "fenced_frames/report2.html"}}],
+          {data: {'mockResult':1}});
+    )")
+                           .ExtractString());
+
+  // There are three "worklet operations": one `addModule()` and two
+  // `selectURL()`.
+  test_worklet_host_manager()
+      .GetAttachedWorkletHost()
+      ->WaitForWorkletResponsesCount(2);
+
+  FrameTreeNode* fenced_frame_root_node = CreateFencedFrame(urn_uuid);
+
+  std::string event_data1 = "this is a click";
+  EXPECT_TRUE(
+      ExecJs(fenced_frame_root_node,
+             JsReplace("window.fence.reportEvent({"
+                       "  eventType: 'click',"
+                       "  eventData: $1,"
+                       "  destination: ['shared-storage-select-url']});",
+                       event_data1)));
+
+  response1.WaitForRequest();
+  EXPECT_EQ(response1.http_request()->content, event_data1);
+
+  std::string event_data2 = "this is a mouse interaction";
+  EXPECT_TRUE(
+      ExecJs(fenced_frame_root_node,
+             JsReplace("window.fence.reportEvent({"
+                       "  eventType: 'mouse interaction',"
+                       "  eventData: $1,"
+                       "  destination: ['shared-storage-select-url']});",
+                       event_data2)));
+
+  response2.WaitForRequest();
+  EXPECT_EQ(response2.http_request()->content, event_data2);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    SharedStorageReportEventBrowserTest,
+    ::testing::Values(
+        blink::features::FencedFramesImplementationType::kShadowDOM,
+        blink::features::FencedFramesImplementationType::kMPArch),
+    &SharedStorageReportEventBrowserTest::DescribeParams);
+
 }  // namespace content
diff --git a/content/browser/shared_storage/shared_storage_document_service_impl.cc b/content/browser/shared_storage/shared_storage_document_service_impl.cc
index 9268cb54..d53427d 100644
--- a/content/browser/shared_storage/shared_storage_document_service_impl.cc
+++ b/content/browser/shared_storage/shared_storage_document_service_impl.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/shared_storage/shared_storage_document_service_impl.h"
 
+#include "base/strings/strcat.h"
 #include "components/services/storage/shared_storage/shared_storage_database.h"
 #include "components/services/storage/shared_storage/shared_storage_manager.h"
 #include "content/browser/shared_storage/shared_storage_worklet_host.h"
@@ -13,9 +14,22 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_client.h"
 #include "third_party/blink/public/common/shared_storage/shared_storage_utils.h"
+#include "url/url_constants.h"
 
 namespace content {
 
+namespace {
+
+// TODO(crbug.com/1335504): Consider moving this function to
+// third_party/blink/common/fenced_frame/fenced_frame_utils.cc.
+bool IsValidFencedFrameReportingURL(const GURL& url) {
+  if (!url.is_valid())
+    return false;
+  return url.SchemeIs(url::kHttpsScheme);
+}
+
+}  // namespace
+
 const char kSharedStorageDisabledMessage[] = "sharedStorage is disabled";
 
 // static
@@ -86,7 +100,8 @@
 
 void SharedStorageDocumentServiceImpl::RunURLSelectionOperationOnWorklet(
     const std::string& name,
-    const std::vector<GURL>& urls,
+    std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+        urls_with_metadata,
     const std::vector<uint8_t>& serialized_data,
     RunURLSelectionOperationOnWorkletCallback callback) {
   if (render_frame_host().IsNestedWithinFencedFrame()) {
@@ -97,7 +112,7 @@
     return;
   }
 
-  if (!blink::IsValidSharedStorageURLsArrayLength(urls.size())) {
+  if (!blink::IsValidSharedStorageURLsArrayLength(urls_with_metadata.size())) {
     // This could indicate a compromised renderer, so let's terminate it.
     receiver_.ReportBadMessage(
         "Attempted to execute RunURLSelectionOperationOnWorklet with invalid "
@@ -105,6 +120,30 @@
     return;
   }
 
+  for (const auto& url_with_metadata : urls_with_metadata) {
+    // TODO(crbug.com/1318970): Use `blink::IsValidFencedFrameURL()` here.
+    if (!url_with_metadata->url.is_valid()) {
+      // This could indicate a compromised renderer, since the URLs were already
+      // validated in the renderer.
+      receiver_.ReportBadMessage(
+          base::StrCat({"Invalid fenced frame URL '",
+                        url_with_metadata->url.possibly_invalid_spec(), "'"}));
+      return;
+    }
+
+    for (const auto& metadata_pair : url_with_metadata->reporting_metadata) {
+      if (!IsValidFencedFrameReportingURL(metadata_pair.second)) {
+        // This could indicate a compromised renderer, since the reporting URLs
+        // were already validated in the renderer.
+        receiver_.ReportBadMessage(
+            base::StrCat({"Invalid reporting URL '",
+                          metadata_pair.second.possibly_invalid_spec(),
+                          "' for '", metadata_pair.first, "'"}));
+        return;
+      }
+    }
+  }
+
   if (!IsSharedStorageAllowed()) {
     std::move(callback).Run(/*success=*/false,
                             /*error_message=*/kSharedStorageDisabledMessage,
@@ -113,7 +152,8 @@
   }
 
   GetSharedStorageWorkletHost()->RunURLSelectionOperationOnWorklet(
-      name, urls, serialized_data, std::move(callback));
+      name, std::move(urls_with_metadata), serialized_data,
+      std::move(callback));
 }
 
 void SharedStorageDocumentServiceImpl::SharedStorageSet(
diff --git a/content/browser/shared_storage/shared_storage_document_service_impl.h b/content/browser/shared_storage/shared_storage_document_service_impl.h
index a439035..b907f4a 100644
--- a/content/browser/shared_storage/shared_storage_document_service_impl.h
+++ b/content/browser/shared_storage/shared_storage_document_service_impl.h
@@ -52,7 +52,8 @@
                              RunOperationOnWorkletCallback callback) override;
   void RunURLSelectionOperationOnWorklet(
       const std::string& name,
-      const std::vector<GURL>& urls,
+      std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+          urls_with_metadata,
       const std::vector<uint8_t>& serialized_data,
       RunURLSelectionOperationOnWorkletCallback callback) override;
   void SharedStorageSet(const std::u16string& key,
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.cc b/content/browser/shared_storage/shared_storage_worklet_host.cc
index 9d770bf..fdc89a88 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.cc
+++ b/content/browser/shared_storage/shared_storage_worklet_host.cc
@@ -3,8 +3,9 @@
 // found in the LICENSE file.
 
 #include "content/browser/shared_storage/shared_storage_worklet_host.h"
-#include "components/services/storage/shared_storage/public/mojom/shared_storage.mojom.h"
 
+#include "components/services/storage/shared_storage/public/mojom/shared_storage.mojom.h"
+#include "components/services/storage/shared_storage/shared_storage_manager.h"
 #include "content/browser/devtools/devtools_instrumentation.h"
 #include "content/browser/renderer_host/page_impl.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
@@ -31,18 +32,20 @@
 SharedStorageURNMappingResult CalculateSharedStorageURNMappingResult(
     bool script_execution_succeeded,
     const url::Origin& shared_storage_origin,
-    const std::vector<GURL>& urls,
+    std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+        urls_with_metadata,
     uint32_t index,
     double budget_remaining,
     bool& failed_due_to_no_budget) {
   DCHECK(!failed_due_to_no_budget);
-  DCHECK_GT(urls.size(), 0u);
-  DCHECK_LT(index, urls.size());
+  DCHECK_GT(urls_with_metadata.size(), 0u);
+  DCHECK_LT(index, urls_with_metadata.size());
   DCHECK(script_execution_succeeded || index == 0);
 
   double budget_to_charge =
-      (urls.size() > 1u)
-          ? (script_execution_succeeded ? std::log2(urls.size()) : 1.0)
+      (urls_with_metadata.size() > 1u)
+          ? (script_execution_succeeded ? std::log2(urls_with_metadata.size())
+                                        : 1.0)
           : 0.0;
 
   // If we are running out of budget, consider this mapping to be failed. Use
@@ -53,13 +56,13 @@
     budget_to_charge = 0.0;
   }
 
-  GURL mapped_url = urls[index];
+  GURL mapped_url = urls_with_metadata[index]->url;
 
-  return SharedStorageURNMappingResult{
-      .mapped_url = mapped_url,
-      .metadata =
-          SharedStorageBudgetMetadata{.origin = shared_storage_origin,
-                                      .budget_to_charge = budget_to_charge}};
+  return SharedStorageURNMappingResult(
+      mapped_url,
+      SharedStorageBudgetMetadata{.origin = shared_storage_origin,
+                                  .budget_to_charge = budget_to_charge},
+      urls_with_metadata[index]->reporting_metadata);
 }
 
 }  // namespace
@@ -92,13 +95,13 @@
   auto it = unresolved_urns_.begin();
   while (it != unresolved_urns_.end()) {
     const GURL& urn_uuid = it->first;
-    const std::vector<GURL>& urls = it->second;
 
     bool failed_due_to_no_budget = false;
     page_->fenced_frame_urls_map().OnSharedStorageURNMappingResultDetermined(
         urn_uuid,
         CalculateSharedStorageURNMappingResult(
-            /*script_execution_succeeded=*/false, shared_storage_origin_, urls,
+            /*script_execution_succeeded=*/false, shared_storage_origin_,
+            std::move(it->second),
             /*index=*/0, /*budget_remaining=*/0.0, failed_due_to_no_budget));
 
     it = unresolved_urns_.erase(it);
@@ -169,7 +172,8 @@
 
 void SharedStorageWorkletHost::RunURLSelectionOperationOnWorklet(
     const std::string& name,
-    const std::vector<GURL>& urls,
+    std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+        urls_with_metadata,
     const std::vector<uint8_t>& serialized_data,
     blink::mojom::SharedStorageDocumentService::
         RunURLSelectionOperationOnWorkletCallback callback) {
@@ -190,7 +194,12 @@
 
   GURL urn_uuid = page_->fenced_frame_urls_map().GeneratePendingMappedURN();
 
-  bool emplace_succeeded = unresolved_urns_.emplace(urn_uuid, urls).second;
+  std::vector<GURL> urls;
+  for (const auto& url_with_metadata : urls_with_metadata)
+    urls.emplace_back(url_with_metadata->url);
+
+  bool emplace_succeeded =
+      unresolved_urns_.emplace(urn_uuid, std::move(urls_with_metadata)).second;
 
   // Assert that `urn_uuid` was not in the set before.
   DCHECK(emplace_succeeded);
@@ -537,15 +546,17 @@
   auto it = unresolved_urns_.find(urn_uuid);
   DCHECK(it != unresolved_urns_.end());
 
-  std::vector<GURL> urls = std::move(it->second);
+  std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+      urls_with_metadata = std::move(it->second);
   unresolved_urns_.erase(it);
 
   if (page_) {
     bool failed_due_to_no_budget = false;
     SharedStorageURNMappingResult mapping_result =
         CalculateSharedStorageURNMappingResult(
-            script_execution_succeeded, shared_storage_origin_, urls, index,
-            budget_result.bits, failed_due_to_no_budget);
+            script_execution_succeeded, shared_storage_origin_,
+            std::move(urls_with_metadata), index, budget_result.bits,
+            failed_due_to_no_budget);
 
     if (document_service_) {
       DCHECK(!IsInKeepAlivePhase());
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.h b/content/browser/shared_storage/shared_storage_worklet_host.h
index 663df4b..2d4472e 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.h
+++ b/content/browser/shared_storage/shared_storage_worklet_host.h
@@ -66,7 +66,8 @@
                              const std::vector<uint8_t>& serialized_data);
   void RunURLSelectionOperationOnWorklet(
       const std::string& name,
-      const std::vector<GURL>& urls,
+      std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>
+          urls_with_metadata,
       const std::vector<uint8_t>& serialized_data,
       blink::mojom::SharedStorageDocumentService::
           RunURLSelectionOperationOnWorkletCallback callback);
@@ -198,12 +199,13 @@
   // the value of the main frame origin in the constructor.
   const url::Origin main_frame_origin_;
 
-  // A map of unresolved URNs to the candidate URL vector. Inside
+  // A map of unresolved URNs to the candidate URL with metadata vector. Inside
   // `RunURLSelectionOperationOnWorklet()` a new URN is generated and is
   // inserted into `unresolved_urns_`. When the corresponding
   // `OnRunURLSelectionOperationOnWorkletFinished()` is called, the URN is
   // removed from `unresolved_urns_`.
-  std::map<GURL, std::vector<GURL>> unresolved_urns_;
+  std::map<GURL, std::vector<blink::mojom::SharedStorageUrlWithMetadataPtr>>
+      unresolved_urns_;
 
   // The number of unfinished worklet requests, including `addModule()`,
   // `selectURL()`, or `run()`.
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 35c08a6..2aec7fc 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -6086,7 +6086,8 @@
 // On Mac and Android, the reported menu coordinates are relative to the
 // OOPIF, and its screen position is computed later, so this test isn't
 // relevant on those platforms.
-#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMECAST)
+// This has been disabled on CastOS due to flakiness per crbug.com/1074249.
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CASTOS)
 IN_PROC_BROWSER_TEST_F(SitePerProcessHitTestBrowserTest,
                        ScrolledNestedPopupMenuTest) {
   GURL main_url(embedded_test_server()->GetURL(
@@ -6196,7 +6197,7 @@
   // they access deleted state.
   RunPostedTasks();
 }
-#endif  // !BUILDFLAG(IS_ANDROID)
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CASTOS)
 
 #if defined(USE_AURA)
 class SitePerProcessGestureHitTestBrowserTest
diff --git a/content/browser/tracing/cast_tracing_agent.cc b/content/browser/tracing/cast_tracing_agent.cc
index ab450b3..ef35223b 100644
--- a/content/browser/tracing/cast_tracing_agent.cc
+++ b/content/browser/tracing/cast_tracing_agent.cc
@@ -190,9 +190,11 @@
       return;
     }
 
-    trace_writer_ = std::make_unique<tracing::SystemTraceWriter<std::string>>(
-        producer_, target_buffer_,
-        tracing::SystemTraceWriter<std::string>::TraceType::kFTrace);
+    trace_writer_ = std::make_unique<SystemTraceWriter>(
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+        producer_,
+#endif
+        target_buffer_, SystemTraceWriter::TraceType::kFTrace);
     stop_complete_callback_ = std::move(stop_complete_callback);
     session_->StopTracing(base::BindRepeating(&CastDataSource::OnTraceData,
                                               base::Unretained(this)));
@@ -205,6 +207,14 @@
 
  private:
   friend class base::NoDestructor<CastDataSource>;
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  using DataSourceProxy =
+      tracing::PerfettoTracedProcess::DataSourceProxy<CastDataSource>;
+  using SystemTraceWriter =
+      tracing::SystemTraceWriter<std::string, DataSourceProxy>;
+#else
+  using SystemTraceWriter = tracing::SystemTraceWriter<std::string>;
+#endif
 
   CastDataSource()
       : DataSourceBase(tracing::mojom::kSystemTraceDataSourceName),
@@ -212,6 +222,12 @@
             {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
              base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
     DETACH_FROM_SEQUENCE(perfetto_sequence_checker_);
+    tracing::PerfettoTracedProcess::Get()->AddDataSource(this);
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+    perfetto::DataSourceDescriptor dsd;
+    dsd.set_name(tracing::mojom::kSystemTraceDataSourceName);
+    DataSourceProxy::Register(dsd, this);
+#endif
   }
 
   void SystemTracerStarted(bool success) {
@@ -258,7 +274,7 @@
   std::unique_ptr<CastSystemTracingSession> session_;
   bool session_started_ = false;
   base::OnceClosure session_started_callback_;
-  std::unique_ptr<tracing::SystemTraceWriter<std::string>> trace_writer_;
+  std::unique_ptr<SystemTraceWriter> trace_writer_;
   base::OnceClosure stop_complete_callback_;
   uint32_t target_buffer_ = 0;
 };
diff --git a/content/browser/tracing/cros_tracing_agent.cc b/content/browser/tracing/cros_tracing_agent.cc
index 58add84..1e5ddbb 100644
--- a/content/browser/tracing/cros_tracing_agent.cc
+++ b/content/browser/tracing/cros_tracing_agent.cc
@@ -130,10 +130,26 @@
 
  private:
   friend class base::NoDestructor<CrOSDataSource>;
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  using DataSourceProxy =
+      tracing::PerfettoTracedProcess::DataSourceProxy<CastDataSource>;
+  using SystemTraceWriter =
+      tracing::SystemTraceWriter<scoped_refptr<base::RefCountedString>,
+                                 DataSourceProxy>;
+#else
+  using SystemTraceWriter =
+      tracing::SystemTraceWriter<scoped_refptr<base::RefCountedString>>;
+#endif
 
   CrOSDataSource()
       : DataSourceBase(tracing::mojom::kSystemTraceDataSourceName) {
     DETACH_FROM_SEQUENCE(ui_sequence_checker_);
+    tracing::PerfettoTracedProcess::Get()->AddDataSource(this);
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+    perfetto::DataSourceDescriptor dsd;
+    dsd.set_name(mojom::kSystemTraceDataSourceName);
+    DataSourceProxy::Register(dsd, this);
+#endif
   }
 
   void StartTracingOnUI(tracing::PerfettoProducer* producer,
@@ -181,11 +197,11 @@
       return;
     }
 
-    trace_writer_ = std::make_unique<
-        tracing::SystemTraceWriter<scoped_refptr<base::RefCountedString>>>(
-        producer_, target_buffer_,
-        tracing::SystemTraceWriter<
-            scoped_refptr<base::RefCountedString>>::TraceType::kFTrace);
+    trace_writer_ = std::make_unique<SystemTraceWriter>(
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+        producer_,
+#endif
+        target_buffer_, SystemTraceWriter::TraceType::kFTrace);
     trace_writer_->WriteData(events);
     trace_writer_->Flush(base::BindOnce(&CrOSDataSource::OnTraceDataCommitted,
                                         base::Unretained(this),
@@ -220,9 +236,7 @@
   bool session_started_ = false;
   base::OnceClosure on_session_started_callback_;
   uint32_t target_buffer_ = 0;
-  std::unique_ptr<
-      tracing::SystemTraceWriter<scoped_refptr<base::RefCountedString>>>
-      trace_writer_;
+  std::unique_ptr<SystemTraceWriter> trace_writer_;
 };
 
 }  // namespace
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc
index 2b838004..172202a 100644
--- a/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -490,11 +490,7 @@
 }
 
 // Only CrOS and Cast support system tracing.
-// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
-// complete.
-#if BUILDFLAG(IS_CHROMEOS_ASH) || \
-    (BUILDFLAG(IS_CHROMECAST) &&  \
-     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)))
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CASTOS)
 #define MAYBE_SystemTraceEvents SystemTraceEvents
 #else
 #define MAYBE_SystemTraceEvents DISABLED_SystemTraceEvents
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
index 62944e6f..df1a5cc7 100644
--- a/content/browser/utility_process_host.cc
+++ b/content/browser/utility_process_host.cc
@@ -118,7 +118,11 @@
   return StartProcess();
 }
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 void UtilityProcessHost::RunServiceDeprecated(
     const std::string& service_name,
     mojo::ScopedMessagePipeHandle service_pipe,
@@ -368,7 +372,11 @@
 
 void UtilityProcessHost::OnProcessLaunched() {
   launch_state_ = LaunchState::kLaunchComplete;
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   for (auto& callback : pending_run_service_callbacks_)
     std::move(callback).Run(process_->GetProcess().Pid());
   pending_run_service_callbacks_.clear();
@@ -379,7 +387,11 @@
 
 void UtilityProcessHost::OnProcessLaunchFailed(int error_code) {
   launch_state_ = LaunchState::kLaunchFailed;
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   for (auto& callback : pending_run_service_callbacks_)
     std::move(callback).Run(absl::nullopt);
   pending_run_service_callbacks_.clear();
diff --git a/content/browser/utility_process_host.h b/content/browser/utility_process_host.h
index b5784b7..bfb6040 100644
--- a/content/browser/utility_process_host.h
+++ b/content/browser/utility_process_host.h
@@ -23,7 +23,11 @@
 #include "sandbox/policy/mojom/sandbox.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 #include "base/callback.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #endif
@@ -93,7 +97,11 @@
   // Starts the utility process.
   bool Start();
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   // Instructs the utility process to run an instance of the named service,
   // bound to |service_pipe|. This is DEPRECATED and should never be used.
   using RunServiceDeprecatedCallback =
@@ -166,7 +174,11 @@
   };
   LaunchState launch_state_ = LaunchState::kLaunchInProgress;
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   // Collection of callbacks to be run once the process is actually started (or
   // fails to start).
   std::vector<RunServiceDeprecatedCallback> pending_run_service_callbacks_;
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 58b1c4c..9c6c301 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -354,8 +354,12 @@
   // implemented in u2fd.
   if (base::FeatureList::IsEnabled(device::kWebAuthCrosPlatformAuthenticator) &&
       !is_u2f_api_request) {
+    // There are two possible PIDs the virtual U2F HID device could use, with or
+    // without corp protocol functionality.
     constexpr device::VidPid kChromeOsU2fdVidPid{0x18d1, 0x502c};
-    discovery_factory->set_hid_ignore_list({kChromeOsU2fdVidPid});
+    constexpr device::VidPid kChromeOsU2fdCorpVidPid{0x18d1, 0x5212};
+    discovery_factory->set_hid_ignore_list(
+        {kChromeOsU2fdVidPid, kChromeOsU2fdCorpVidPid});
     discovery_factory->set_generate_request_id_callback(
         GetWebAuthenticationDelegate()->GetGenerateRequestIdCallback(
             render_frame_host));
diff --git a/content/browser/webauth/client_data_json.cc b/content/browser/webauth/client_data_json.cc
index c65d369b..9c3e329b 100644
--- a/content/browser/webauth/client_data_json.cc
+++ b/content/browser/webauth/client_data_json.cc
@@ -30,11 +30,12 @@
   ret.push_back('"');
 
   const char* const in_bytes = in.data();
-  const size_t length = in.size();
-  size_t offset = 0;
+  // ICU uses |int32_t| for lengths.
+  const int32_t length = base::checked_cast<int32_t>(in.size());
+  int32_t offset = 0;
 
   while (offset < length) {
-    const size_t prior_offset = offset;
+    const int32_t prior_offset = offset;
     // Input strings must be valid UTF-8.
     base_icu::UChar32 codepoint;
     CHECK(base::ReadUnicodeCharacter(in_bytes, length, &offset, &codepoint));
diff --git a/content/child/dwrite_font_proxy/font_fallback_win.cc b/content/child/dwrite_font_proxy/font_fallback_win.cc
index de6d056..4435749 100644
--- a/content/child/dwrite_font_proxy/font_fallback_win.cc
+++ b/content/child/dwrite_font_proxy/font_fallback_win.cc
@@ -97,13 +97,10 @@
 
   locale = locale ? locale : L"";
 
-  size_t mapped_length_size_t = *mapped_length;
   if (GetCachedFont(text_chunk, base_family_name, locale, base_weight,
-                    base_style, base_stretch, mapped_font,
-                    &mapped_length_size_t)) {
+                    base_style, base_stretch, mapped_font, mapped_length)) {
     DCHECK(*mapped_font);
-    DCHECK_GT(mapped_length_size_t, 0u);
-    *mapped_length = base::checked_cast<UINT32>(mapped_length_size_t);
+    DCHECK_GT(*mapped_length, 0u);
     LogFallbackResult(SUCCESS_CACHE);
     return S_OK;
   }
@@ -175,7 +172,7 @@
                                  DWRITE_FONT_STYLE base_style,
                                  DWRITE_FONT_STRETCH base_stretch,
                                  IDWriteFont** font,
-                                 size_t* mapped_length) {
+                                 uint32_t* mapped_length) {
   base::AutoLock guard(lock_);
   std::map<std::wstring, std::list<mswr::ComPtr<IDWriteFontFamily>>>::iterator
       it = fallback_family_cache_.find(MakeCacheKey(base_family_name, locale));
@@ -200,9 +197,9 @@
     // different from |mapped_length| because ReadUnicodeCharacter can advance
     // |character_index| even if the character cannot be mapped (invalid
     // surrogate pair or font does not contain a matching glyph).
-    size_t character_index = 0;
-    size_t length = 0;  // How much of the text can actually be mapped.
-    while (character_index < text.length()) {
+    int32_t character_index = 0;
+    uint32_t length = 0;  // How much of the text can actually be mapped.
+    while (static_cast<uint32_t>(character_index) < text.length()) {
       BOOL exists = false;
       base_icu::UChar32 character = 0;
       if (!base::ReadUnicodeCharacter(text.c_str(), text.length(),
diff --git a/content/child/dwrite_font_proxy/font_fallback_win.h b/content/child/dwrite_font_proxy/font_fallback_win.h
index 6bc0230..f3778a13 100644
--- a/content/child/dwrite_font_proxy/font_fallback_win.h
+++ b/content/child/dwrite_font_proxy/font_fallback_win.h
@@ -65,7 +65,7 @@
                      DWRITE_FONT_STYLE base_style,
                      DWRITE_FONT_STRETCH base_stretch,
                      IDWriteFont** mapped_font,
-                     size_t* mapped_length) LOCKS_EXCLUDED(lock_);
+                     uint32_t* mapped_length) LOCKS_EXCLUDED(lock_);
 
   void AddCachedFamily(Microsoft::WRL::ComPtr<IDWriteFontFamily> family,
                        const wchar_t* base_family_name,
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc
index 6a2971e6..8e08690 100644
--- a/content/common/child_process_host_impl.cc
+++ b/content/common/child_process_host_impl.cc
@@ -182,7 +182,11 @@
   return peer_process_;
 }
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 void ChildProcessHostImpl::RunServiceDeprecated(
     const std::string& service_name,
     mojo::ScopedMessagePipeHandle service_pipe) {
diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h
index 97c3b9e..68fc500 100644
--- a/content/common/child_process_host_impl.h
+++ b/content/common/child_process_host_impl.h
@@ -78,7 +78,12 @@
   bool IsChannelOpening() override;
   void AddFilter(IPC::MessageFilter* filter) override;
   void BindReceiver(mojo::GenericPendingReceiver receiver) override;
-#if BUILDFLAG(IS_CHROMECAST)
+
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   void RunServiceDeprecated(
       const std::string& service_name,
       mojo::ScopedMessagePipeHandle service_pipe) override;
diff --git a/content/common/features.gni b/content/common/features.gni
index 0fa6f2ac..1381ddc5 100644
--- a/content/common/features.gni
+++ b/content/common/features.gni
@@ -10,7 +10,8 @@
 
   # Whether to perform critical memory pressure handling when in foreground (if
   # false, critical memory pressure is treated like moderate pressure in foreground).
-  allow_critical_memory_pressure_handling_in_foreground = is_chromecast
+  allow_critical_memory_pressure_handling_in_foreground =
+      is_castos || is_cast_android
 
   # Whether or not MBI mode (Multiple Blink Isolates) should be enabled,
   # depending on the build argument.
diff --git a/content/public/browser/message_port_provider.h b/content/public/browser/message_port_provider.h
index c413cc77..15e99c9 100644
--- a/content/public/browser/message_port_provider.h
+++ b/content/public/browser/message_port_provider.h
@@ -18,7 +18,12 @@
 #include "base/android/scoped_java_ref.h"
 #endif
 
-#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1329657): The last IS_FUCHSIA check will not be needed once
+// its build sets enable_cast_receiver.
+#if BUILDFLAG(ENABLE_CAST_RECEIVER) &&                    \
+        (BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CASTOS) || \
+         BUILDFLAG(IS_CAST_ANDROID)) ||                   \
+    BUILDFLAG(IS_FUCHSIA)
 #include "third_party/blink/public/common/messaging/message_port_channel.h"
 #endif
 
@@ -52,7 +57,12 @@
       const base::android::JavaParamRef<jobjectArray>& ports);
 #endif  // BUILDFLAG(IS_ANDROID)
 
-#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1329657): The last IS_FUCHSIA check will not be needed once
+// its build sets enable_cast_receiver.
+#if BUILDFLAG(ENABLE_CAST_RECEIVER) &&                    \
+        (BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CASTOS) || \
+         BUILDFLAG(IS_CAST_ANDROID)) ||                   \
+    BUILDFLAG(IS_FUCHSIA)
   // If |target_origin| is unset, then no origin scoping is applied.
   static void PostMessageToFrame(
       Page& page,
@@ -60,7 +70,7 @@
       const absl::optional<std::u16string>& target_origin,
       const std::u16string& data,
       std::vector<blink::WebMessagePort> ports);
-#endif  // BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CHROMECAST)
+#endif
 };
 
 }  // namespace content
diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h
index 4ef5bcf..02213f9 100644
--- a/content/public/browser/service_process_host.h
+++ b/content/public/browser/service_process_host.h
@@ -24,7 +24,12 @@
 #include "sandbox/policy/mojom/sandbox.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
+#include "base/callback.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #endif
 
@@ -176,7 +181,11 @@
                      sandbox::mojom::Sandbox sandbox);
 };
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 // DEPRECATED. DO NOT USE THIS. This is a helper for any remaining service
 // launching code which uses an older code path to launch services in a utility
 // process. All new code must use ServiceProcessHost instead of this API.
@@ -186,7 +195,7 @@
     sandbox::mojom::Sandbox sandbox_type,
     mojo::ScopedMessagePipeHandle service_pipe,
     base::OnceCallback<void(base::ProcessId)> callback);
-#endif
+#endif  // BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 
 }  // namespace content
 
diff --git a/content/public/common/child_process_host.h b/content/public/common/child_process_host.h
index 77d8c2c..e046908 100644
--- a/content/public/common/child_process_host.h
+++ b/content/public/common/child_process_host.h
@@ -17,7 +17,11 @@
 #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
 #include <string>
 
 #include "mojo/public/cpp/system/message_pipe.h"
@@ -177,7 +181,11 @@
   //   3. Main thread, ChildThreadImpl::BindReceiver (virtual).
   virtual void BindReceiver(mojo::GenericPendingReceiver receiver) = 0;
 
-#if BUILDFLAG(IS_CHROMECAST)
+// TODO(crbug.com/1328879): Remove this method when fixing the bug.
+// TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition once
+// such builds no longer reach this file.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID) || \
+    (BUILDFLAG(IS_FUCHSIA) && BUILDFLAG(IS_CHROMECAST))
   // Instructs the child process to run an instance of the named service. This
   // is DEPRECATED and should never be used.
   virtual void RunServiceDeprecated(
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index b4a8a8b..d90cb01 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -407,7 +407,7 @@
 
   ui::fuchsia::IgnorePresentCallsForTest();
 
-  // Clear the per-process cached BuildInfo, which was initialized by
+  // Clear the per-process cached system info, which was initialized by
   // TestSuite::Initialize(), to prevent a DCHECK for multiple calls during
   // in-process browser tests. There is not a single TestSuite for all browser
   // tests and some use the cached values, so skipping the earlier
@@ -597,10 +597,7 @@
   base::i18n::AllowMultipleInitializeCallsForTesting();
   base::i18n::InitializeICU();
 
-  ContentMainDelegate* delegate = GetCustomContentMainDelegate();
-  if (!delegate)
-    delegate = GetContentMainDelegateForTesting();
-
+  ContentMainDelegate* delegate = GetContentMainDelegateForTesting();
   // The delegate should have been set by JNI_OnLoad for the test target.
   DCHECK(delegate);
 
@@ -728,8 +725,6 @@
   auto params = CopyContentMainParams();
   params.ui_task = std::move(ui_task);
   params.created_main_parts_closure = std::move(created_main_parts_closure);
-  if (auto* custom_delegate = GetCustomContentMainDelegate())
-    params.delegate = custom_delegate;
   EXPECT_EQ(expected_exit_code_, ContentMain(std::move(params)));
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -1130,8 +1125,4 @@
   CreatedBrowserMainParts(browser_main_parts);
 }
 
-ContentMainDelegate* BrowserTestBase::GetCustomContentMainDelegate() {
-  return nullptr;
-}
-
 }  // namespace content
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h
index a537032..c91fdc83 100644
--- a/content/public/test/browser_test_base.h
+++ b/content/public/test/browser_test_base.h
@@ -42,7 +42,6 @@
 
 namespace content {
 class BrowserMainParts;
-class ContentMainDelegate;
 class WebContents;
 
 class BrowserTestBase : public ::testing::Test {
@@ -123,12 +122,6 @@
   // PreEarlyInitialization() has been called.
   virtual void CreatedBrowserMainParts(BrowserMainParts* browser_main_parts) {}
 
-  // Override this to provide a custom ContentMainDelegate for the test. The
-  // returned object must live at least until
-  // TearDownInProcessBrowserTextFixture is called. If nullptr is returned the
-  // test will use the default delegate.
-  virtual ContentMainDelegate* GetCustomContentMainDelegate();
-
   // GTest assertions that the connection to `network_service_test_` did not get
   // dropped unexpectedly.
   void AssertThatNetworkServiceDidNotCrash();
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index 8298176..09e04eb 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -83,7 +83,7 @@
                                  subprocess_path);
 #endif
 
-#if defined(USE_AURA) && defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_CHROMECAST)
+#if defined(USE_AURA) && defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_CASTOS)
   // https://crbug.com/695054: Ignore window activation/deactivation to make
   // the Chrome-internal focus unaffected by OS events caused by running tests
   // in parallel.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index d462598..cb87db0 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -363,14 +363,15 @@
     ]
   }
 
-  if (enable_media_remoting || is_chromecast) {
+  # TODO(crbug.com/1293520): Remove this dependency on cast devices.
+  if (enable_media_remoting || is_castos || is_cast_android) {
     deps += [ "//media/mojo/mojom:remoting" ]
 
     if (enable_media_remoting) {
       deps += [ "//media/remoting:remoting_sender" ]
     }
 
-    if (is_chromecast) {
+    if (is_castos || is_cast_android) {
       if (enable_cast_audio_renderer) {
         sources += [
           "media/cast_renderer_factory.cc",
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc
index d551edb..f209783 100644
--- a/content/renderer/media/media_factory.cc
+++ b/content/renderer/media/media_factory.cc
@@ -112,12 +112,12 @@
 #include "content/renderer/media/cast_renderer_factory.h"
 #endif  // BUILDFLAG(ENABLE_CAST_AUDIO_RENDERER)
 
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 // Enable remoting receiver
 #include "media/remoting/receiver_controller.h"        // nogncheck
 #include "media/remoting/remoting_constants.h"         // nogncheck
 #include "media/remoting/remoting_renderer_factory.h"  // nogncheck
-#endif
+#endif  // BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 
 #if BUILDFLAG(IS_WIN)
 #include "content/renderer/media/win/dcomp_texture_wrapper_impl.h"
@@ -708,7 +708,7 @@
   }
 #endif  // BUILDFLAG(IS_WIN)
 
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
   if (renderer_media_playback_options.is_remoting_renderer_enabled()) {
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
     auto default_factory_remoting = std::make_unique<CastRendererClientFactory>(
@@ -732,7 +732,7 @@
         RendererType::kRemoting, std::move(remoting_renderer_factory),
         is_remoting_media);
   }
-#endif  // BUILDFLAG(IS_CHROMECAST)
+#endif  // BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 
   if (!is_base_renderer_factory_set) {
     // TODO(crbug.com/1265448): These sorts of checks shouldn't be necessary if
diff --git a/content/renderer/media/media_factory.h b/content/renderer/media/media_factory.h
index eab869c..599ecec 100644
--- a/content/renderer/media/media_factory.h
+++ b/content/renderer/media/media_factory.h
@@ -26,7 +26,7 @@
 
 #if BUILDFLAG(ENABLE_MEDIA_REMOTING)
 // Needed by remoting sender.
-#include "media/mojo/mojom/remoting.mojom.h"
+#include "media/mojo/mojom/remoting.mojom.h"  // nogncheck
 #endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
 
 namespace blink {
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 2ee2fdb..95eafaf 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -28,8 +28,9 @@
   import("//v8/gni/v8.gni")
 }
 
-# TODO(spang): Investigate using shell_views with is_chromecast=true.
-shell_use_toolkit_views = toolkit_views && !is_chromecast
+# TODO(crbug.com/1336055, spang): Investigate using shell_views with cast builds as
+# true.
+shell_use_toolkit_views = toolkit_views && !is_castos
 
 declare_args() {
   content_shell_product_name = "Content Shell"
diff --git a/content/shell/fuchsia/content_shell.cmx b/content/shell/fuchsia/content_shell.cmx
index b1d2a6fd..6fdf012 100644
--- a/content/shell/fuchsia/content_shell.cmx
+++ b/content/shell/fuchsia/content_shell.cmx
@@ -15,6 +15,7 @@
       "fuchsia.buildinfo.Provider",
       "fuchsia.device.NameProvider",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 86d4ad4..6fffb3e9 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -985,7 +985,7 @@
     deps += [ "//content/public/browser" ]
   }
 
-  if (use_aura && toolkit_views && !is_chromecast) {
+  if (use_aura && toolkit_views && !is_castos) {
     deps += [ "//ui/views" ]
   }
 
@@ -1701,7 +1701,7 @@
       sources += [ "../browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc" ]
 
       # For chromecast, content_browsertests does not provide a shell window.
-      if (use_aura && !is_chromecast) {
+      if (use_aura && !is_castos) {
         sources += [ "../browser/media/capture/aura_window_video_capture_device_browsertest.cc" ]
       }
     }
@@ -1826,7 +1826,6 @@
   } else {
     # Non-Android.
     sources += [
-      "../app/content_main_runner_impl_browsertest.cc",
       "../browser/direct_sockets/direct_sockets_open_browsertest.cc",
       "../browser/direct_sockets/direct_sockets_tcp_browsertest.cc",
       "../browser/direct_sockets/direct_sockets_udp_browsertest.cc",
@@ -1847,7 +1846,6 @@
     ]
     deps += [
       "//content/public/browser:proto",
-      "//sandbox/policy",
       "//ui/base/clipboard:clipboard_test_support",
     ]
     data += [ "//content/test/data/clipboard/" ]
@@ -1968,7 +1966,7 @@
     ]
   }
 
-  if (is_chromecast) {
+  if (is_castos || is_cast_android) {
     sources -= [
       # The cast shell media pipeline doesn't produce real video frames that we
       # can inspect.
@@ -3005,7 +3003,8 @@
     deps += [ "//device/vr:vr_fakes" ]
   }
 
-  if (is_chromecast) {
+  # TODO(crbug.com/1293538): Update to check is_cast_audio_only
+  if (is_castos || is_cast_android) {
     deps += [ "//chromecast:chromecast_buildflags" ]
   }
 }
diff --git a/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node-expected-uia-win.txt b/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node-expected-uia-win.txt
new file mode 100644
index 0000000..7a8dc99
--- /dev/null
+++ b/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node-expected-uia-win.txt
@@ -0,0 +1,5 @@
+AriaProperties changed on role=description, name=After
+AriaProperties changed on role=group
+LiveRegionChanged on role=group
+StructureChanged/ChildAdded on role=group
+StructureChanged/ChildrenReordered on role=document
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node.html b/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node.html
new file mode 100644
index 0000000..12d5747
--- /dev/null
+++ b/content/test/data/accessibility/event/live-region-change-on-freshly-unignored-node.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="live" aria-live="polite" style="display: none;">Before</div>
+<script>
+  function go() {
+    let live = document.getElementById('live');
+    live.setAttribute("style", "");
+    live.firstChild.data = 'After';
+  }
+</script>
+</body>
+</html>
diff --git a/content/test/data/cache_transparency/cacheable.html b/content/test/data/cache_transparency/cacheable.html
new file mode 100644
index 0000000..fe7d8988
--- /dev/null
+++ b/content/test/data/cache_transparency/cacheable.html
@@ -0,0 +1,6 @@
+<html>
+  <head><title>Cacheable Test Page</title></head>
+  <body>
+    <script type="application/javascript" src="/cache_transparency/cacheable.js"></script>
+  </body>
+</html>
diff --git a/content/test/data/cache_transparency/cacheable.js b/content/test/data/cache_transparency/cacheable.js
new file mode 100644
index 0000000..21ec3e93
--- /dev/null
+++ b/content/test/data/cache_transparency/cacheable.js
@@ -0,0 +1,6 @@
+// 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.
+
+// A file with no special properties except that is is cacheable due to its
+// headers. Used by CacheTransparency tests.
diff --git a/content/test/data/cache_transparency/cacheable.js.mock-http-headers b/content/test/data/cache_transparency/cacheable.js.mock-http-headers
new file mode 100644
index 0000000..d97b0434
--- /dev/null
+++ b/content/test/data/cache_transparency/cacheable.js.mock-http-headers
@@ -0,0 +1,2 @@
+200 HTTP/1.1 OK
+Cache-Control: max-age=10000
diff --git a/content/test/data/cache_transparency/pervasive.html b/content/test/data/cache_transparency/pervasive.html
new file mode 100644
index 0000000..e86fd96e
--- /dev/null
+++ b/content/test/data/cache_transparency/pervasive.html
@@ -0,0 +1,6 @@
+<html>
+  <head><title>Pervasive Payload Test page</title></head>
+  <body>
+    <script type="application/javascript" src="/cache_transparency/pervasive.js"></script>
+  </body>
+</html>
diff --git a/content/test/data/cache_transparency/pervasive.js b/content/test/data/cache_transparency/pervasive.js
new file mode 100644
index 0000000..0aaa971
--- /dev/null
+++ b/content/test/data/cache_transparency/pervasive.js
@@ -0,0 +1,5 @@
+// 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.
+
+// Dummy file for Cache Transparency tests.
diff --git a/content/test/data/cache_transparency/pervasive.js.mock-http-headers b/content/test/data/cache_transparency/pervasive.js.mock-http-headers
new file mode 100644
index 0000000..5b2b7df
--- /dev/null
+++ b/content/test/data/cache_transparency/pervasive.js.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: application/javascript
+Cache-Control: max-age=10000
diff --git a/content/test/data/fenced_frames/report1.html b/content/test/data/fenced_frames/report1.html
new file mode 100644
index 0000000..2526072
--- /dev/null
+++ b/content/test/data/fenced_frames/report1.html
@@ -0,0 +1,4 @@
+<html>
+<head></head>
+<body>This page has no title.</body>
+</html>
diff --git a/content/test/data/fenced_frames/report2.html b/content/test/data/fenced_frames/report2.html
new file mode 100644
index 0000000..2526072
--- /dev/null
+++ b/content/test/data/fenced_frames/report2.html
@@ -0,0 +1,4 @@
+<html>
+<head></head>
+<body>This page has no title.</body>
+</html>
diff --git a/content/test/fenced_frame_test_utils.cc b/content/test/fenced_frame_test_utils.cc
index 4336ed35..0469304 100644
--- a/content/test/fenced_frame_test_utils.cc
+++ b/content/test/fenced_frame_test_utils.cc
@@ -12,6 +12,8 @@
 
 namespace content {
 
+using SharedStorageReportingMap = base::flat_map<std::string, ::GURL>;
+
 FrameTreeNode* GetFencedFrameRootNode(FrameTreeNode* node) {
   if (blink::features::kFencedFramesImplementationTypeParam.Get() ==
       blink::features::FencedFramesImplementationType::kShadowDOM) {
@@ -28,13 +30,18 @@
     const GURL& urn_uuid,
     const GURL& mapped_url,
     const url::Origin& shared_storage_origin,
-    double budget_to_charge) {
-  FencedFrameURLMapping::SharedStorageBudgetMetadata metadata = {
+    double budget_to_charge,
+    const std::string& report_event,
+    const GURL& report_url) {
+  FencedFrameURLMapping::SharedStorageBudgetMetadata budget_metadata = {
       .origin = shared_storage_origin, .budget_to_charge = budget_to_charge};
 
+  SharedStorageReportingMap reporting_map(
+      {std::make_pair(report_event, report_url)});
+
   fenced_frame_url_mapping.OnSharedStorageURNMappingResultDetermined(
-      urn_uuid, FencedFrameURLMapping::SharedStorageURNMappingResult{
-                    .mapped_url = mapped_url, .metadata = metadata});
+      urn_uuid, FencedFrameURLMapping::SharedStorageURNMappingResult(
+                    mapped_url, budget_metadata, reporting_map));
 }
 
 TestFencedFrameURLMappingResultObserver::
diff --git a/content/test/fenced_frame_test_utils.h b/content/test/fenced_frame_test_utils.h
index 1b1f016..7c753fb 100644
--- a/content/test/fenced_frame_test_utils.h
+++ b/content/test/fenced_frame_test_utils.h
@@ -24,7 +24,9 @@
     const GURL& urn_uuid,
     const GURL& mapped_url,
     const url::Origin& shared_storage_origin,
-    double budget_to_charge);
+    double budget_to_charge,
+    const std::string& report_event = "",
+    const GURL& report_url = GURL());
 
 // Tests can use this class to observe and check the URL mapping result.
 class TestFencedFrameURLMappingResultObserver
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
index 9939b9ad..ff0802a6 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -94,6 +94,9 @@
 crbug.com/1286918 [ android android-pixel-6 ] WebCodecs_TexImage2d_capture [ Failure ]
 crbug.com/1288914 [ android android-pixel-6 ] WebCodecs_TexImage2d_camera [ Failure ]
 
+crbug.com/1336713 WebCodecs_texture_expired_from_destroyed_device_hw_decoder [ Failure ]
+crbug.com/1336713 WebCodecs_texture_expired_from_destroyed_device_sw_decoder [ Failure ]
+
 crbug.com/1311091 WebCodecs_WebRTCPeerConnection_* [ Skip ]
 
 #######################################################################
diff --git a/content/web_test/BUILD.gn b/content/web_test/BUILD.gn
index 00cce83..1319db8 100644
--- a/content/web_test/BUILD.gn
+++ b/content/web_test/BUILD.gn
@@ -143,7 +143,7 @@
       "browser/web_test_browser_main_platform_support_mac.mm",
       "browser/web_test_shell_platform_delegate_mac.mm",
     ]
-  } else if (toolkit_views && !is_chromecast) {
+  } else if (toolkit_views && !is_castos) {
     sources += [ "browser/web_test_shell_platform_delegate_views.cc" ]
   } else {
     sources += [ "browser/web_test_shell_platform_delegate_aura.cc" ]
diff --git a/device/bluetooth/floss/floss_dbus_client.h b/device/bluetooth/floss/floss_dbus_client.h
index c890b6c..b39d4e6 100644
--- a/device/bluetooth/floss/floss_dbus_client.h
+++ b/device/bluetooth/floss/floss_dbus_client.h
@@ -118,6 +118,39 @@
     base::OnceCallback<void(const absl::optional<T>& ret,
                             const absl::optional<Error>& err)>;
 
+// A Weakly Owned ResponseCallback<T>. The main usecase for this is to have
+// a weak pointer available for |PostDelayedTask|, where deleting the main
+// object will automatically cancel the posted task.
+template <typename T>
+class WeaklyOwnedCallback {
+ public:
+  explicit WeaklyOwnedCallback(ResponseCallback<T> cb) : cb_(std::move(cb)) {}
+  ~WeaklyOwnedCallback() = default;
+
+  static std::unique_ptr<WeaklyOwnedCallback> Create(ResponseCallback<T> cb) {
+    return std::make_unique<WeaklyOwnedCallback>(std::move(cb));
+  }
+
+  // If the callback hasn't been executed, run it and return true. Otherwise
+  // false.
+  bool Run(const absl::optional<T>& ret, const absl::optional<Error>& err) {
+    if (cb_) {
+      std::move(cb_).Run(ret, err);
+      return true;
+    }
+
+    return false;
+  }
+
+  base::WeakPtr<WeaklyOwnedCallback> GetWeakPtr() const {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  ResponseCallback<T> cb_;
+  base::WeakPtrFactory<WeaklyOwnedCallback> weak_ptr_factory_{this};
+};
+
 // Restrict all access to DBus client initialization to FlossDBusManager so we
 // can enforce the proper ordering of initialization and shutdowns.
 class FlossDBusClient {
diff --git a/device/bluetooth/floss/floss_manager_client.cc b/device/bluetooth/floss/floss_manager_client.cc
index 91519c7..f9c3b72 100644
--- a/device/bluetooth/floss/floss_manager_client.cc
+++ b/device/bluetooth/floss/floss_manager_client.cc
@@ -100,6 +100,15 @@
 // static
 const char FlossManagerClient::kObjectManagerPath[] = "/";
 
+// static
+const int FlossManagerClient::kSetFlossRetryCount = 3;
+
+// static
+const int FlossManagerClient::kSetFlossRetryDelayMs = 500;
+
+// static
+const int FlossManagerClient::kSetFlossEnabledDBusTimeoutMs = 10000;
+
 FlossManagerClient::FlossManagerClient() = default;
 
 FlossManagerClient::~FlossManagerClient() {
@@ -147,24 +156,63 @@
   return false;
 }
 
-void FlossManagerClient::SetFlossEnabled(bool enabled) {
+void FlossManagerClient::GetFlossEnabledWithTarget(bool target,
+                                                   int retry,
+                                                   int retry_wait_ms) {
   dbus::ObjectProxy* object_proxy =
       bus_->GetObjectProxy(service_name_, dbus::ObjectPath(kManagerObject));
   if (!object_proxy) {
+    if (set_floss_enabled_callback_) {
+      set_floss_enabled_callback_->Run(absl::nullopt,
+                                       Error(kUnknownManagerError, ""));
+      set_floss_enabled_callback_.reset();
+    }
+    return;
+  }
+
+  DVLOG(2) << __func__;
+
+  dbus::MethodCall method_call(kManagerInterface, manager::kGetFlossEnabled);
+  dbus::MessageWriter writer(&method_call);
+
+  object_proxy->CallMethodWithErrorResponse(
+      &method_call, kDBusTimeoutMs,
+      base::BindOnce(&FlossManagerClient::HandleGetFlossEnabled,
+                     weak_ptr_factory_.GetWeakPtr(), target, retry,
+                     retry_wait_ms));
+}
+
+void FlossManagerClient::SetFlossEnabled(
+    bool enabled,
+    int retry,
+    int retry_wait_ms,
+    absl::optional<ResponseCallback<bool>> cb) {
+  dbus::ObjectProxy* object_proxy =
+      bus_->GetObjectProxy(service_name_, dbus::ObjectPath(kManagerObject));
+  if (!object_proxy) {
+    if (cb) {
+      std::move(*cb).Run(/*ret=*/absl::nullopt,
+                         /*err=*/Error(kUnknownManagerError, ""));
+    }
     return;
   }
 
   DVLOG(1) << __func__;
 
+  if (cb) {
+    set_floss_enabled_callback_ =
+        WeaklyOwnedCallback<bool>::Create(std::move(*cb));
+  }
+
   dbus::MethodCall method_call(kManagerInterface, manager::kSetFlossEnabled);
   dbus::MessageWriter writer(&method_call);
   writer.AppendBool(enabled);
 
   object_proxy->CallMethodWithErrorResponse(
-      &method_call, kDBusTimeoutMs,
-      base::BindOnce(&FlossManagerClient::DefaultResponse,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     "FlossManagerClient::SetFlossEnabled"));
+      &method_call, kSetFlossEnabledDBusTimeoutMs,
+      base::BindOnce(&FlossManagerClient::HandleSetFlossEnabled,
+                     weak_ptr_factory_.GetWeakPtr(), enabled, retry,
+                     retry_wait_ms));
 }
 
 void FlossManagerClient::SetAdapterEnabled(int adapter,
@@ -203,7 +251,8 @@
     dbus::ErrorResponse* error_response) {
   // Only handle error cases since non-error called in OnHciEnabledChange
   if (powered_callback_ && (!response || error_response)) {
-    powered_callback_.release()->RunError();
+    powered_callback_->RunError();
+    powered_callback_.reset();
   }
 }
 
@@ -309,7 +358,11 @@
   // Get manager ready.
   RegisterWithManager();
 
-  SetFlossEnabled(base::FeatureList::IsEnabled(floss::features::kFlossEnabled));
+  // Enable Floss and retry a few times until it is set.
+  SetFlossEnabled(base::FeatureList::IsEnabled(floss::features::kFlossEnabled),
+                  kSetFlossRetryCount, kSetFlossRetryDelayMs,
+                  base::BindOnce(&FlossManagerClient::CompleteSetFlossEnabled,
+                                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 void FlossManagerClient::HandleGetAvailableAdapters(
@@ -407,7 +460,8 @@
   }
 
   if (adapter == GetDefaultAdapter() && powered_callback_) {
-    powered_callback_.release()->RunNoError();
+    powered_callback_->RunNoError();
+    powered_callback_.reset();
   }
 
   adapter_to_powered_[adapter] = enabled;
@@ -419,6 +473,101 @@
   std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
 }
 
+void FlossManagerClient::HandleSetFlossEnabled(
+    bool target,
+    int retry,
+    int retry_wait_ms,
+    dbus::Response* response,
+    dbus::ErrorResponse* error_response) {
+  // Failed to call |SetFlossEnabled| so first log the error and post a delayed
+  // set if there are retries left.
+  if (!response) {
+    FlossDBusClient::LogErrorResponse(
+        "FlossManagerClient::HandleSetFlossEnabled", error_response);
+    if (retry > 0) {
+      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&FlossManagerClient::SetFlossEnabled,
+                         weak_ptr_factory_.GetWeakPtr(), target, retry - 1,
+                         retry_wait_ms, absl::nullopt),
+          base::Milliseconds(retry_wait_ms));
+    } else if (set_floss_enabled_callback_) {
+      set_floss_enabled_callback_->Run(
+          /*ret=*/absl::nullopt,
+          ErrorResponseToError(kUnknownManagerError, "", error_response));
+      set_floss_enabled_callback_.reset();
+    }
+
+    return;
+  }
+
+  GetFlossEnabledWithTarget(target, retry, retry_wait_ms);
+}
+
+void FlossManagerClient::HandleGetFlossEnabled(
+    bool target,
+    int retry,
+    int retry_wait_ms,
+    dbus::Response* response,
+    dbus::ErrorResponse* error_response) {
+  if (!response) {
+    FlossDBusClient::LogErrorResponse(
+        "FlossManagerClient::HandleGetFlossEnabled", error_response);
+    if (retry > 0) {
+      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&FlossManagerClient::GetFlossEnabledWithTarget,
+                         weak_ptr_factory_.GetWeakPtr(), target, retry - 1,
+                         retry_wait_ms),
+          base::Milliseconds(retry_wait_ms));
+    } else if (set_floss_enabled_callback_) {
+      set_floss_enabled_callback_->Run(
+          /*ret=*/absl::nullopt,
+          ErrorResponseToError(kUnknownManagerError, "", error_response));
+      set_floss_enabled_callback_.reset();
+    }
+
+    return;
+  }
+
+  bool floss_enabled = false;
+  dbus::MessageReader msg(response);
+  if (!msg.PopBool(&floss_enabled)) {
+    LOG(ERROR) << "Response to GetFlossEnabled was not a bool";
+    return;
+  }
+
+  // Target doesn't match reality. Retry |SetFlossEnabled|.
+  if (floss_enabled != target && retry > 0) {
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&FlossManagerClient::SetFlossEnabled,
+                       weak_ptr_factory_.GetWeakPtr(), target, retry - 1,
+                       retry_wait_ms, absl::nullopt),
+        base::Milliseconds(kSetFlossRetryDelayMs));
+  } else {
+    DVLOG(1) << "Floss is currently "
+             << (floss_enabled ? "enabled" : "disabled") << " and target was "
+             << (target ? "enabled" : "disabled");
+    if (set_floss_enabled_callback_) {
+      set_floss_enabled_callback_->Run(floss_enabled,
+                                       /*err=*/absl::nullopt);
+      set_floss_enabled_callback_.reset();
+    }
+  }
+}
+
+void FlossManagerClient::CompleteSetFlossEnabled(
+    const absl::optional<bool>& ret,
+    const absl::optional<Error>& err) {
+  if (err) {
+    LOG(ERROR) << "Floss couldn't be enabled. Error=" << err->name << ", "
+               << err->message;
+  } else {
+    DVLOG(1) << "Completed SetFlossEnabled with value " << *ret;
+  }
+}
+
 dbus::PropertySet* FlossManagerClient::CreateProperties(
     dbus::ObjectProxy* object_proxy,
     const dbus::ObjectPath& object_path,
diff --git a/device/bluetooth/floss/floss_manager_client.h b/device/bluetooth/floss/floss_manager_client.h
index 5d695bb..6a96dc61 100644
--- a/device/bluetooth/floss/floss_manager_client.h
+++ b/device/bluetooth/floss/floss_manager_client.h
@@ -104,12 +104,6 @@
   // Check whether the given adapter is present on the system.
   virtual bool GetAdapterPresent(int adapter) const;
 
-  // Enable or disable Floss at the platform level. This will only be used while
-  // Floss is being developed behind a feature flag. This api will be called on
-  // the manager to stop Bluez from running and let Floss manage the adapters
-  // instead.
-  virtual void SetFlossEnabled(bool enable);
-
   // Check whether an adapter is enabled.
   virtual bool GetAdapterEnabled(int adapter) const;
 
@@ -126,6 +120,24 @@
  protected:
   friend class FlossManagerClientTest;
 
+  // Check whether Floss is currently enabled. If the response matches the
+  // target, continue. If it doesn't, retry setting the target value (with
+  // a short delay) until the number of retries is 0.
+  virtual void GetFlossEnabledWithTarget(bool target,
+                                         int retry,
+                                         int retry_wait_ms);
+
+  // Enable or disable Floss at the platform level. This will only be used while
+  // Floss is being developed behind a feature flag. This api will be called on
+  // the manager to stop Bluez from running and let Floss manage the adapters
+  // instead. If setting this value fails, it will be automatically retried
+  // several times with delays. Once the value of |GetFlossEnabled| matches
+  // |enable| (or an error occurs), the ResponseCallback will be called.
+  virtual void SetFlossEnabled(bool enable,
+                               int retry,
+                               int retry_wait_ms,
+                               absl::optional<ResponseCallback<bool>> cb);
+
   // Handle response to |GetAvailableAdapters| DBus method call.
   virtual void HandleGetAvailableAdapters(dbus::Response* response,
                                           dbus::ErrorResponse* error);
@@ -140,6 +152,24 @@
       dbus::MethodCall* method_call,
       dbus::ExportedObject::ResponseSender response_sender);
 
+  // Handle response to |SetFlossEnabled|.
+  virtual void HandleSetFlossEnabled(bool target,
+                                     int retry,
+                                     int retry_wait_ms,
+                                     dbus::Response* response,
+                                     dbus::ErrorResponse* error_response);
+
+  // Handle response to |GetFlossEnabled|.
+  virtual void HandleGetFlossEnabled(bool target,
+                                     int retry,
+                                     int retry_wait_ms,
+                                     dbus::Response* response,
+                                     dbus::ErrorResponse* error_response);
+
+  // Completion of |SetFlossEnabled|.
+  virtual void CompleteSetFlossEnabled(const absl::optional<bool>& ret,
+                                       const absl::optional<Error>& err);
+
   // Get active adapters and register for callbacks with manager object.
   void RegisterWithManager();
 
@@ -192,9 +222,24 @@
   // Floss Manager registers ObjectManager at this path.
   static const char kObjectManagerPath[];
 
+  // Retry SetFlossEnabled until the value sticks.
+  static const int kSetFlossRetryCount;
+
+  // Amount of time to wait when retrying |SetFlossEnabled|.
+  static const int kSetFlossRetryDelayMs;
+
+  // Custom timeout on DBus for |SetFlossEnabled| call. Since this call does
+  // multiple things synchronously, give it a little bit more time to complete
+  // (especially because it's crucial to set this correctly for Floss to be
+  // enabled).
+  static const int kSetFlossEnabledDBusTimeoutMs;
+
   // Powered callback called only when adapter actually powers on
   std::unique_ptr<PoweredCallback> powered_callback_;
 
+  // Callback sent for SetFlossEnabled completion.
+  std::unique_ptr<WeaklyOwnedCallback<bool>> set_floss_enabled_callback_;
+
   base::WeakPtrFactory<FlossManagerClient> weak_ptr_factory_{this};
 };
 
diff --git a/device/bluetooth/floss/floss_manager_client_unittest.cc b/device/bluetooth/floss/floss_manager_client_unittest.cc
index d464cdf..bb1e7150 100644
--- a/device/bluetooth/floss/floss_manager_client_unittest.cc
+++ b/device/bluetooth/floss/floss_manager_client_unittest.cc
@@ -101,15 +101,19 @@
 
     // Handle method calls on the object proxy
     ON_CALL(*manager_object_proxy_.get(), DoCallMethodWithErrorResponse)
-        .WillByDefault(
-            [this](::dbus::MethodCall* method_call, int timeout_ms,
-                   ::dbus::ObjectProxy::ResponseOrErrorCallback* cb) {
-              if (method_call->GetMember() == manager::kGetAvailableAdapters) {
-                HandleGetAvailableAdapters(method_call, timeout_ms, cb);
-              }
+        .WillByDefault([this](
+                           ::dbus::MethodCall* method_call, int timeout_ms,
+                           ::dbus::ObjectProxy::ResponseOrErrorCallback* cb) {
+          if (method_call->GetMember() == manager::kGetAvailableAdapters) {
+            HandleGetAvailableAdapters(method_call, timeout_ms, cb);
+          } else if (method_call->GetMember() == manager::kSetFlossEnabled) {
+            HandleSetFlossEnabled(method_call, timeout_ms, cb);
+          } else if (method_call->GetMember() == manager::kGetFlossEnabled) {
+            HandleGetFlossEnabled(method_call, timeout_ms, cb);
+          }
 
-              method_called_[method_call->GetMember()]++;
-            });
+          method_called_[method_call->GetMember()]++;
+        });
   }
 
   void SendHciDeviceCallback(int adapter,
@@ -200,6 +204,44 @@
     std::move(*cb).Run(response.get(), nullptr);
   }
 
+  void HandleSetFlossEnabled(::dbus::MethodCall* method_call,
+                             int timeout_ms,
+                             ::dbus::ObjectProxy::ResponseOrErrorCallback* cb) {
+    method_call->SetSerial(serial_++);
+    if (fail_setfloss_count_ > 0) {
+      fail_setfloss_count_--;
+
+      std::string error_name("org.foo.bar");
+      std::string error_message("SetFlossEnabled failed");
+      auto error = ::dbus::ErrorResponse::FromMethodCall(
+          method_call, error_name, error_message);
+      std::move(*cb).Run(nullptr, error.get());
+    } else {
+      auto response = ::dbus::Response::CreateEmpty();
+      std::move(*cb).Run(response.get(), nullptr);
+    }
+  }
+
+  void HandleGetFlossEnabled(::dbus::MethodCall* method_call,
+                             int timeout_ms,
+                             ::dbus::ObjectProxy::ResponseOrErrorCallback* cb) {
+    method_call->SetSerial(serial_++);
+    if (fail_getfloss_count_ > 0) {
+      fail_getfloss_count_--;
+
+      std::string error_name("org.foo.bar");
+      std::string error_message("GetFlossEnabled failed");
+      auto error = ::dbus::ErrorResponse::FromMethodCall(
+          method_call, error_name, error_message);
+      std::move(*cb).Run(nullptr, error.get());
+    } else {
+      auto response = ::dbus::Response::CreateEmpty();
+      ::dbus::MessageWriter writer(response.get());
+      writer.AppendBool(floss_enabled_target_);
+      std::move(*cb).Run(response.get(), nullptr);
+    }
+  }
+
   void ExpectErrorResponse(std::unique_ptr<dbus::Response> response) {
     EXPECT_EQ(response->GetMessageType(),
               dbus::Message::MessageType::MESSAGE_ERROR);
@@ -226,6 +268,25 @@
   }
 
  protected:
+  void SetFlossEnabled(bool enable,
+                       int retry_count,
+                       int retry_ms,
+                       base::RepeatingClosure quitloop) {
+    client_->SetFlossEnabled(enable, retry_count, retry_ms,
+                             GetQuitLoopCallback(quitloop));
+  }
+
+  void EndRunLoopCallback(base::RepeatingClosure quit,
+                          const absl::optional<bool>& ret,
+                          const absl::optional<Error>& err) {
+    std::move(quit).Run();
+  }
+
+  ResponseCallback<bool> GetQuitLoopCallback(base::RepeatingClosure quit) {
+    return base::BindOnce(&FlossManagerClientTest::EndRunLoopCallback,
+                          weak_ptr_factory_.GetWeakPtr(), std::move(quit));
+  }
+
   // DBus messages require an increasing serial number or the dbus libraries
   // assert.
   int serial_ = 1;
@@ -236,7 +297,12 @@
   scoped_refptr<::dbus::ObjectManager> object_manager_;
   std::map<std::string, int> method_called_;
 
-  base::test::TaskEnvironment task_environment_;
+  // Testing the |SetFlossEnabled| retry with a target of enabling Floss.
+  int fail_setfloss_count_ = 0;
+  int fail_getfloss_count_ = 0;
+  bool floss_enabled_target_ = true;
+
+  base::test::SingleThreadTaskEnvironment task_environment_;
   base::WeakPtrFactory<FlossManagerClientTest> weak_ptr_factory_{this};
 };
 
@@ -382,4 +448,28 @@
   EXPECT_TRUE(method_called_[manager::kGetAvailableAdapters] > 0);
   EXPECT_TRUE(method_called_[manager::kRegisterCallback] > 0);
 }
+
+TEST_F(FlossManagerClientTest, SetFlossEnabledRetries) {
+  base::RunLoop loop;
+
+  TestManagerObserver observer(client_.get());
+  floss_enabled_target_ = false;
+  client_->Init(bus_.get(), kManagerInterface, /*adapter_path=*/std::string());
+
+  // First confirm we had it set to False
+  EXPECT_EQ(method_called_[manager::kSetFlossEnabled], 1);
+  EXPECT_EQ(method_called_[manager::kGetFlossEnabled], 1);
+
+  method_called_.clear();
+
+  // Retries up to 3 times across both Get and Set.
+  fail_setfloss_count_ = 1;
+  fail_getfloss_count_ = 1;
+  floss_enabled_target_ = true;
+  SetFlossEnabled(true, 3, 0, loop.QuitClosure());
+  loop.Run();
+
+  EXPECT_EQ(method_called_[manager::kSetFlossEnabled], 2);
+  EXPECT_EQ(method_called_[manager::kGetFlossEnabled], 2);
+}
 }  // namespace floss
diff --git a/fuchsia_web/runners/cast/cast_runner.cc b/fuchsia_web/runners/cast/cast_runner.cc
index 8b8c8fd3..a132087c 100644
--- a/fuchsia_web/runners/cast/cast_runner.cc
+++ b/fuchsia_web/runners/cast/cast_runner.cc
@@ -50,6 +50,7 @@
     // "fuchsia.camera3.DeviceWatcher" is redirected to the agent.
     "fuchsia.device.NameProvider",
     "fuchsia.fonts.Provider",
+    "fuchsia.hwinfo.Product",
     "fuchsia.input.virtualkeyboard.ControllerCreator",
     "fuchsia.intl.PropertyProvider",
     // "fuchsia.legacymetrics.MetricsRecorder" is redirected to the agent.
diff --git a/fuchsia_web/runners/cast/cast_runner.cml b/fuchsia_web/runners/cast/cast_runner.cml
index 2359fd1..f14c2f54 100644
--- a/fuchsia_web/runners/cast/cast_runner.cml
+++ b/fuchsia_web/runners/cast/cast_runner.cml
@@ -46,6 +46,7 @@
         "fuchsia.feedback.ComponentDataRegister",
         "fuchsia.feedback.CrashReportingProductRegister",
         "fuchsia.fonts.Provider",
+        "fuchsia.hwinfo.Product",
         "fuchsia.input.virtualkeyboard.ControllerCreator",
         "fuchsia.intl.PropertyProvider",
         // "fuchsia.legacymetrics.MetricsRecorder",
diff --git a/fuchsia_web/runners/cast/cast_runner.cmx b/fuchsia_web/runners/cast/cast_runner.cmx
index 7c0f37f9..eaf7f8b 100644
--- a/fuchsia_web/runners/cast/cast_runner.cmx
+++ b/fuchsia_web/runners/cast/cast_runner.cmx
@@ -15,6 +15,7 @@
       "fuchsia.feedback.ComponentDataRegister",
       "fuchsia.feedback.CrashReportingProductRegister",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
diff --git a/fuchsia_web/runners/web/web_runner.cmx b/fuchsia_web/runners/web/web_runner.cmx
index cf99c070..c98e487 100644
--- a/fuchsia_web/runners/web/web_runner.cmx
+++ b/fuchsia_web/runners/web/web_runner.cmx
@@ -14,6 +14,7 @@
       "fuchsia.feedback.ComponentDataRegister",
       "fuchsia.feedback.CrashReportingProductRegister",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
diff --git a/fuchsia_web/webengine/test/web_engine_shell.cmx b/fuchsia_web/webengine/test/web_engine_shell.cmx
index 7b303c6..a14d635 100644
--- a/fuchsia_web/webengine/test/web_engine_shell.cmx
+++ b/fuchsia_web/webengine/test/web_engine_shell.cmx
@@ -16,6 +16,7 @@
       "fuchsia.feedback.ComponentDataRegister",
       "fuchsia.feedback.CrashReportingProductRegister",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.logger.LogSink",
diff --git a/fuchsia_web/webengine/web_instance.cmx b/fuchsia_web/webengine/web_instance.cmx
index d6a05145..4163a99 100644
--- a/fuchsia_web/webengine/web_instance.cmx
+++ b/fuchsia_web/webengine/web_instance.cmx
@@ -15,6 +15,7 @@
       "fuchsia.camera3.DeviceWatcher",
       "fuchsia.device.NameProvider",
       "fuchsia.fonts.Provider",
+      "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
       "fuchsia.intl.PropertyProvider",
       "fuchsia.legacymetrics.MetricsRecorder",
diff --git a/fuchsia_web/webinstance_host/web_instance_host.cc b/fuchsia_web/webinstance_host/web_instance_host.cc
index b291b1e..d0bc11f 100644
--- a/fuchsia_web/webinstance_host/web_instance_host.cc
+++ b/fuchsia_web/webinstance_host/web_instance_host.cc
@@ -355,12 +355,12 @@
   // at:
   //   https://fuchsia.dev/reference/fidl/fuchsia.web#CreateContextParams.service_directory
   std::vector<std::string> services{
-      "fuchsia.buildinfo.Provider", "fuchsia.device.NameProvider",
-      "fuchsia.fonts.Provider",     "fuchsia.intl.PropertyProvider",
-      "fuchsia.logger.LogSink",     "fuchsia.memorypressure.Provider",
-      "fuchsia.process.Launcher",
+      "fuchsia.buildinfo.Provider",      "fuchsia.device.NameProvider",
+      "fuchsia.fonts.Provider",          "fuchsia.hwinfo.Product",
+      "fuchsia.intl.PropertyProvider",   "fuchsia.logger.LogSink",
+      "fuchsia.memorypressure.Provider", "fuchsia.process.Launcher",
       "fuchsia.settings.Display",  // Used if preferred theme is DEFAULT.
-      "fuchsia.sysmem.Allocator",   "fuchsia.ui.scenic.Scenic"};
+      "fuchsia.sysmem.Allocator",        "fuchsia.ui.scenic.Scenic"};
 
   // TODO(crbug.com/1209031): Provide these conditionally, once corresponding
   // ContextFeatureFlags have been defined.
diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc
index 0adc026..8422f5c 100644
--- a/gin/array_buffer.cc
+++ b/gin/array_buffer.cc
@@ -73,7 +73,8 @@
 
 // static
 void ArrayBufferAllocator::InitializePartition() {
-  static base::NoDestructor<base::PartitionAllocator> partition_allocator{};
+  static base::NoDestructor<partition_alloc::PartitionAllocator>
+      partition_allocator{};
 
   // These configuration options are copied from blink's ArrayBufferPartition.
   partition_allocator->init({
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
index 8d5944e..d150b31 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
@@ -44,8 +44,9 @@
 }  // namespace
 
 SharedImageBackingFactoryOzone::SharedImageBackingFactoryOzone(
-    SharedContextState* shared_context_state)
-    : shared_context_state_(shared_context_state) {
+    SharedContextState* shared_context_state,
+    const GpuDriverBugWorkarounds& workarounds)
+    : shared_context_state_(shared_context_state), workarounds_(workarounds) {
 #if BUILDFLAG(USE_DAWN)
   dawn_procs_ = base::MakeRefCounted<base::RefCountedData<DawnProcTable>>(
       dawn::native::GetProcs());
@@ -88,7 +89,7 @@
   return std::make_unique<SharedImageBackingOzone>(
       mailbox, format, gfx::BufferPlane::DEFAULT, size, color_space,
       surface_origin, alpha_type, usage, shared_context_state_.get(),
-      std::move(pixmap), dawn_procs_);
+      std::move(pixmap), dawn_procs_, workarounds_);
 }
 
 std::unique_ptr<SharedImageBacking>
@@ -164,7 +165,7 @@
     backing = std::make_unique<SharedImageBackingOzone>(
         mailbox, plane_format, plane, plane_size, color_space, surface_origin,
         alpha_type, usage, shared_context_state_.get(), std::move(pixmap),
-        dawn_procs_);
+        dawn_procs_, workarounds_);
     backing->SetCleared();
   } else if (handle.type == gfx::SHARED_MEMORY_BUFFER) {
     SharedMemoryRegionWrapper shm_wrapper;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.h b/gpu/command_buffer/service/shared_image_backing_factory_ozone.h
index d041b915..f76df8d 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.h
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.h
@@ -10,12 +10,12 @@
 #include "base/memory/scoped_refptr.h"
 #include "gpu/command_buffer/service/shared_image_backing_factory.h"
 #include "gpu/command_buffer/service/shared_image_backing_ozone.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/gpu_gles2_export.h"
 
 struct DawnProcTable;
 
 namespace gpu {
-
 class SharedContextState;
 
 // Implementation of SharedImageBackingFactory that produces NativePixmap
@@ -24,7 +24,8 @@
     : public SharedImageBackingFactory {
  public:
   explicit SharedImageBackingFactoryOzone(
-      SharedContextState* shared_context_state);
+      SharedContextState* shared_context_state,
+      const GpuDriverBugWorkarounds& workarounds);
 
   ~SharedImageBackingFactoryOzone() override;
 
@@ -78,6 +79,7 @@
 
   const raw_ptr<SharedContextState> shared_context_state_;
   scoped_refptr<base::RefCountedData<DawnProcTable>> dawn_procs_;
+  const GpuDriverBugWorkarounds workarounds_;
 
   std::unique_ptr<SharedImageBackingOzone> CreateSharedImageInternal(
       const Mailbox& mailbox,
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.cc b/gpu/command_buffer/service/shared_image_backing_ozone.cc
index 3b1b9bf..c4aabcd 100644
--- a/gpu/command_buffer/service/shared_image_backing_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_ozone.cc
@@ -251,7 +251,8 @@
     uint32_t usage,
     scoped_refptr<SharedContextState> context_state,
     scoped_refptr<gfx::NativePixmap> pixmap,
-    scoped_refptr<base::RefCountedData<DawnProcTable>> dawn_procs)
+    scoped_refptr<base::RefCountedData<DawnProcTable>> dawn_procs,
+    const GpuDriverBugWorkarounds& workarounds)
     : ClearTrackingSharedImageBacking(mailbox,
                                       format,
                                       size,
@@ -264,7 +265,8 @@
       plane_(plane),
       pixmap_(std::move(pixmap)),
       dawn_procs_(std::move(dawn_procs)),
-      context_state_(std::move(context_state)) {
+      context_state_(std::move(context_state)),
+      workarounds_(workarounds) {
   bool used_by_skia = (usage & SHARED_IMAGE_USAGE_RASTER) ||
                       (usage & SHARED_IMAGE_USAGE_DISPLAY);
   bool used_by_gl =
@@ -418,8 +420,9 @@
   }
 
   // If current stream is different than last_write_stream_ then wait on that
-  // stream's write_fence_.
-  if (last_write_stream_ != access_stream && !write_fence_.is_null()) {
+  // stream's write_fence_ (except on ARM Mali boards for ChromeOS).
+  if (!write_fence_.is_null() && (workarounds_.add_fence_for_same_gl_context ||
+                                  last_write_stream_ != access_stream)) {
     // For write access we expect new write_fence_ so we can move the old fence
     // here.
     if (!readonly)
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.h b/gpu/command_buffer/service/shared_image_backing_ozone.h
index a1c91f7..bdbcc8f 100644
--- a/gpu/command_buffer/service/shared_image_backing_ozone.h
+++ b/gpu/command_buffer/service/shared_image_backing_ozone.h
@@ -21,6 +21,7 @@
 #include "gpu/command_buffer/service/shared_image_manager.h"
 #include "gpu/command_buffer/service/shared_image_representation.h"
 #include "gpu/command_buffer/service/shared_memory_region_wrapper.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/ipc/common/surface_handle.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/color_space.h"
@@ -48,7 +49,8 @@
       uint32_t usage,
       scoped_refptr<SharedContextState> context_state,
       scoped_refptr<gfx::NativePixmap> pixmap,
-      scoped_refptr<base::RefCountedData<DawnProcTable>> dawn_procs);
+      scoped_refptr<base::RefCountedData<DawnProcTable>> dawn_procs,
+      const GpuDriverBugWorkarounds& workarounds);
 
   SharedImageBackingOzone(const SharedImageBackingOzone&) = delete;
   SharedImageBackingOzone& operator=(const SharedImageBackingOzone&) = delete;
@@ -129,6 +131,7 @@
   // Set for shared memory GMB.
   SharedMemoryRegionWrapper shared_memory_wrapper_;
   scoped_refptr<SharedContextState> context_state_;
+  const GpuDriverBugWorkarounds workarounds_;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc
index 1f37a592b..e8321ec8 100644
--- a/gpu/command_buffer/service/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -384,8 +384,8 @@
 #if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)
   // Desktop Linux, not ChromeOS.
   if (ShouldUseOzoneFactory()) {
-    auto ozone_factory =
-        std::make_unique<SharedImageBackingFactoryOzone>(context_state);
+    auto ozone_factory = std::make_unique<SharedImageBackingFactoryOzone>(
+        context_state, workarounds);
     factories_.push_back(std::move(ozone_factory));
   }
   if (gr_context_type_ == GrContextType::kVulkan &&
@@ -396,8 +396,8 @@
   }
 #elif BUILDFLAG(IS_FUCHSIA)
   if (gr_context_type_ == GrContextType::kVulkan) {
-    auto ozone_factory =
-        std::make_unique<SharedImageBackingFactoryOzone>(context_state);
+    auto ozone_factory = std::make_unique<SharedImageBackingFactoryOzone>(
+        context_state, workarounds);
     factories_.push_back(std::move(ozone_factory));
     auto external_vk_image_factory =
         std::make_unique<ExternalVkImageFactory>(context_state);
@@ -407,8 +407,8 @@
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
   if (gpu_preferences.enable_webgpu ||
       gr_context_type_ == GrContextType::kVulkan) {
-    auto ozone_factory =
-        std::make_unique<SharedImageBackingFactoryOzone>(context_state);
+    auto ozone_factory = std::make_unique<SharedImageBackingFactoryOzone>(
+        context_state, workarounds);
     factories_.push_back(std::move(ozone_factory));
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index b8748f8..32156819 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -4032,6 +4032,19 @@
       "features": [
         "disable_direct_composition_video_overlays"
       ]
+    },
+    {
+      "id": 396,
+      "cr_bugs": [1327044],
+      "description": "Add fence to SharedImageBackingOzone::BeginAccess when on same GL context",
+      "os": {
+        "type": "chromeos"
+      },
+      "gl_vendor": "ARM.*",
+      "gl_renderer": "Mali.*",
+      "features": [
+        "add_fence_for_same_gl_context"
+      ]
     }
   ]
 }
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt
index d36e9b03..c11de6c 100644
--- a/gpu/config/gpu_workaround_list.txt
+++ b/gpu/config/gpu_workaround_list.txt
@@ -1,4 +1,5 @@
 add_and_true_to_loop_condition
+add_fence_for_same_gl_context
 adjust_src_dst_region_for_blitframebuffer
 avoid_one_component_egl_images
 avoid_stencil_buffers
diff --git a/infra/config/generated/builders/try/mac11-arm64-rel-compilator/properties.json b/infra/config/generated/builders/try/mac11-arm64-rel-compilator/properties.json
deleted file mode 100644
index 0635fe26..0000000
--- a/infra/config/generated/builders/try/mac11-arm64-rel-compilator/properties.json
+++ /dev/null
@@ -1,99 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "mac-arm64-rel",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.mac",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_arch": "arm",
-                "target_bits": 64,
-                "target_platform": "mac"
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              }
-            }
-          },
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "mac11-arm64-rel-tests",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.mac",
-              "execution_mode": "TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_arch": "arm",
-                "target_bits": 64,
-                "target_platform": "mac"
-              },
-              "legacy_gclient_config": {
-                "config": "chromium"
-              },
-              "parent": {
-                "bucket": "ci",
-                "builder": "mac-arm64-rel",
-                "project": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "mac-arm64-rel",
-          "project": "chromium"
-        }
-      ],
-      "builder_ids_in_scope_for_testing": [
-        {
-          "bucket": "ci",
-          "builder": "mac11-arm64-rel-tests",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$build/flakiness": {
-    "check_for_flakiness": true
-  },
-  "$build/goma": {
-    "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.mac",
-  "orchestrator": {
-    "builder_group": "tryserver.chromium.mac",
-    "builder_name": "mac11-arm64-rel"
-  },
-  "recipe": "chromium/compilator"
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac11-arm64-rel/properties.json b/infra/config/generated/builders/try/mac11-arm64-rel/properties.json
index 67ab6671..026bb441 100644
--- a/infra/config/generated/builders/try/mac11-arm64-rel/properties.json
+++ b/infra/config/generated/builders/try/mac11-arm64-rel/properties.json
@@ -1,8 +1,4 @@
 {
-  "$build/chromium_orchestrator": {
-    "compilator": "mac11-arm64-rel-compilator",
-    "compilator_watcher_git_revision": "7809a690bbd935bcb3b4d922e24cabe168aaabc8"
-  },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
       "builder_db": {
@@ -81,6 +77,11 @@
   "$build/flakiness": {
     "check_for_flakiness": true
   },
+  "$build/goma": {
+    "rpc_extra_params": "?prod",
+    "server_host": "goma.chromium.org",
+    "use_luci_auth": true
+  },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
     "grouping_keys": [
@@ -89,5 +90,5 @@
     ]
   },
   "builder_group": "tryserver.chromium.mac",
-  "recipe": "chromium/orchestrator"
+  "recipe": "chromium_trybot"
 }
\ No newline at end of file
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md
index 71566dee..8e0a3bc 100644
--- a/infra/config/generated/cq-builders.md
+++ b/infra/config/generated/cq-builders.md
@@ -495,6 +495,3 @@
 * [linux-rel-ml](https://ci.chromium.org/p/chromium/builders/try/linux-rel-ml) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""linux-rel-ml"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""linux-rel-ml""))
   * Experiment percentage: 5.0
 
-* [mac11-arm64-rel](https://ci.chromium.org/p/chromium/builders/try/mac11-arm64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""mac11-arm64-rel"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""mac11-arm64-rel""))
-  * Experiment percentage: 100.0
-
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 41e7486..5255684 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1682,13 +1682,6 @@
       }
       builders {
         name: "chromium/try/mac11-arm64-rel"
-        experiment_percentage: 100
-        location_regexp: ".*"
-        location_regexp_exclude: ".+/[+]/docs/.+"
-        location_regexp_exclude: ".+/[+]/infra/config/.+"
-      }
-      builders {
-        name: "chromium/try/mac11-arm64-rel-compilator"
         includable_only: true
       }
       builders {
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 3cd0f227..1330296 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -71287,11 +71287,11 @@
     builders {
       name: "mac11-arm64-rel"
       swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:mac11-arm64-rel"
-      dimensions: "cores:2"
+      dimensions: "builderless:1"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-18.04"
+      dimensions: "os:Mac"
       dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:1"
       exe {
         cipd_package: "infra/chromium/bootstrapper/${platform}"
         cipd_version: "latest"
@@ -71320,7 +71320,7 @@
         '  },'
         '  "builder_group": "tryserver.chromium.mac",'
         '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/orchestrator"'
+        '  "recipe": "chromium_trybot"'
         '}'
       execution_timeout_secs: 14400
       expiration_secs: 7200
@@ -71332,96 +71332,6 @@
         path: "win_toolchain"
       }
       build_numbers: YES
-      service_account: "chromium-orchestrator@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
-        }
-      }
-      description_html: "This is the orchestrator half of an orchestrator + compilator pair of builders. The compilator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac11-arm64-rel-compilator\">mac11-arm64-rel-compilator</a>."
-    }
-    builders {
-      name: "mac11-arm64-rel-compilator"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:mac11-arm64-rel-compilator"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Mac-11|Mac-12"
-      dimensions: "pool:luci.chromium.try"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/mac11-arm64-rel-compilator/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "tryserver.chromium.mac",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium/compilator"'
-        '}'
-      execution_timeout_secs: 14400
-      expiration_secs: 7200
-      grace_period {
-        seconds: 240
-      }
-      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
@@ -71462,7 +71372,6 @@
           use_invocation_timestamp: true
         }
       }
-      description_html: "This is the compilator half of an orchestrator + compilator pair of builders. The orchestrator is <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac11-arm64-rel\">mac11-arm64-rel</a>."
     }
     builders {
       name: "mac11.0-blink-rel"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 3ea986e5..f7d6d6e 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -2714,12 +2714,6 @@
     name: "buildbucket/luci.chromium.try/mac-updater-try-builder-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/mac11-arm64-rel"
-  }
-  builders {
-    name: "buildbucket/luci.chromium.try/mac11-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/mac12-arm64-rel"
   }
   builders {
@@ -16604,9 +16598,6 @@
     name: "buildbucket/luci.chromium.try/mac11-arm64-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/mac11-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/mac11.0-blink-rel"
   }
   builders {
@@ -17683,9 +17674,6 @@
     name: "buildbucket/luci.chromium.try/mac11-arm64-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/mac11-arm64-rel-compilator"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/mac12-arm64-rel"
   }
   builders {
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
index f3a2c15b..3062c9a 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -112,27 +112,14 @@
     os = os.MAC_DEFAULT,
 )
 
-try_.orchestrator_builder(
+try_.builder(
     name = "mac11-arm64-rel",
+    builderless = True,
     check_for_flakiness = True,
-    compilator = "mac11-arm64-rel-compilator",
     mirrors = [
         "ci/mac-arm64-rel",
         "ci/mac11-arm64-rel-tests",
     ],
-    main_list_view = "try",
-    tryjob = try_.job(
-        experiment_percentage = 100,
-    ),
-)
-
-try_.compilator_builder(
-    name = "mac11-arm64-rel-compilator",
-    check_for_flakiness = True,
-    main_list_view = "try",
-    os = os.MAC_DEFAULT,
-    # TODO (crbug.com/1245171): Revert when root issue is fixed
-    grace_period = 4 * time.minute,
 )
 
 try_.orchestrator_builder(
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 9a7a772..81df166 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -441,18 +441,18 @@
     ]
   }
 
-  if (is_chromeos_ash || is_chromecast) {
+  if (is_chromeos_ash || is_castos || is_cast_android) {
     sources += [
       "test_data.h",
       "wav_audio_handler_unittest.cc",
     ]
+  }
 
-    if (!is_chromecast) {
-      deps += [
-        "//ash/components/audio",
-        "//chromeos/dbus/audio",
-      ]
-    }
+  if (is_chromeos_ash) {
+    deps += [
+      "//ash/components/audio",
+      "//chromeos/dbus/audio",
+    ]
 
     if (use_cras) {
       sources += [
diff --git a/media/audio/audio_device_description.cc b/media/audio/audio_device_description.cc
index 2feaa22..a2d515b8 100644
--- a/media/audio/audio_device_description.cc
+++ b/media/audio/audio_device_description.cc
@@ -58,7 +58,9 @@
 std::string AudioDeviceDescription::GetCommunicationsDeviceName() {
 #if BUILDFLAG(IS_WIN)
   return GetLocalizedStringUTF8(COMMUNICATIONS_AUDIO_DEVICE_NAME);
-#elif BUILDFLAG(IS_CHROMECAST)
+#elif BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
+  // TODO(crbug.com/1336055): Re-evaluate if this is still needed now that CMA
+  // is deprecated.
   return "";
 #else
   NOTREACHED();
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index 1b14b44..2485c8e 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -407,7 +407,7 @@
     deps += [ "//third_party/libvpx" ]
   }
 
-  if (is_linux && !is_chromecast) {
+  if (is_linux && !is_castos) {
     sources += [ "user_input_monitor_linux.cc" ]
   } else if (is_mac) {
     sources += [ "user_input_monitor_mac.cc" ]
@@ -446,11 +446,9 @@
     ]
   }
 
-  # TODO(ziyangch): Check |is_chromecast| first when using cast media pipeline
-  # on Android cast devices.
   if (is_android) {
     sources += [ "demuxer_memory_limit_android.cc" ]
-  } else if (is_chromecast) {
+  } else if (is_castos) {
     sources += [ "demuxer_memory_limit_cast.cc" ]
   } else if (is_fuchsia) {
     sources += [ "demuxer_memory_limit_low.cc" ]
@@ -663,7 +661,7 @@
     ]
   }
 
-  if (is_chromecast && !is_android) {
+  if (is_castos) {
     sources += [ "demuxer_memory_limit_cast_unittest.cc" ]
   }
 }
diff --git a/media/cast/BUILD.gn b/media/cast/BUILD.gn
index 7298d8b..02b5b2f2 100644
--- a/media/cast/BUILD.gn
+++ b/media/cast/BUILD.gn
@@ -316,7 +316,7 @@
 
   # FFMPEG software video decoders are not available on Android and/or
   # Chromecast content_shell builds.
-  if (!is_android && !is_chromecast) {
+  if (!is_android && !is_castos) {
     sources += [
       "test/fake_media_source.cc",
       "test/fake_media_source.h",
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index a4cd06a..9677fa2 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -326,8 +326,8 @@
   }
 
   # libvpx for running vpx test on chromecast doesn't support high bit depth.
-  # This may cause some unit tests failure.
-  if (is_chromecast) {
+  # This may cause some unit tests failure. See b/65382374 for further context.
+  if (is_castos) {
     defines = [ "LIBVPX_NO_HIGH_BIT_DEPTH" ]
   }
 
diff --git a/media/formats/hls/media_playlist.cc b/media/formats/hls/media_playlist.cc
index 9835ece..70f6e81 100644
--- a/media/formats/hls/media_playlist.cc
+++ b/media/formats/hls/media_playlist.cc
@@ -34,6 +34,7 @@
   base::TimeDelta target_duration;
   absl::optional<PartialSegmentInfo> partial_segment_info;
   std::vector<MediaSegment> segments;
+  base::TimeDelta total_duration;
   absl::optional<PlaylistType> playlist_type;
   bool end_list;
   bool i_frames_only;
@@ -324,6 +325,7 @@
   if (!target_duration_tag.has_value()) {
     return ParseStatusCode::kMediaPlaylistMissingTargetDuration;
   }
+  const auto target_duration = target_duration_tag->duration;
 
   absl::optional<PartialSegmentInfo> partial_segment_info;
   if (part_inf_tag.has_value()) {
@@ -332,12 +334,19 @@
   }
 
   // Ensure that no segment exceeds the target duration
+  base::TimeDelta total_duration;
   for (const auto& segment : segments) {
-    const auto duration =
-        static_cast<types::DecimalInteger>(std::round(segment.GetDuration()));
-    if (duration > target_duration_tag->duration) {
+    const auto rounded_duration =
+        std::round(segment.GetDuration().InSecondsF());
+    if (rounded_duration > target_duration.InSecondsF()) {
       return ParseStatusCode::kMediaSegmentExceedsTargetDuration;
     }
+
+    total_duration += segment.GetDuration();
+  }
+
+  if (total_duration.is_max()) {
+    return ParseStatusCode::kPlaylistOverflowsTimeDelta;
   }
 
   // Multivariant playlists may use the `EXT-X-INDEPENDENT-SEGMENTS` tag to
@@ -358,9 +367,10 @@
       CtorArgs{.uri = std::move(uri),
                .version = common_state.GetVersion(),
                .independent_segments = independent_segments,
-               .target_duration = base::Seconds(target_duration_tag->duration),
+               .target_duration = target_duration,
                .partial_segment_info = std::move(partial_segment_info),
                .segments = std::move(segments),
+               .total_duration = total_duration,
                .playlist_type = playlist_type,
                .end_list = end_list_tag.has_value(),
                .i_frames_only = i_frames_only_tag.has_value(),
@@ -372,16 +382,10 @@
       target_duration_(args.target_duration),
       partial_segment_info_(std::move(args.partial_segment_info)),
       segments_(std::move(args.segments)),
+      computed_duration_(args.total_duration),
       playlist_type_(args.playlist_type),
       end_list_(args.end_list),
       i_frames_only_(args.i_frames_only),
-      has_media_sequence_tag_(args.has_media_sequence_tag) {
-  base::TimeDelta duration;
-  for (const auto& segment : segments_) {
-    duration += base::Seconds(segment.GetDuration());
-  }
-
-  computed_duration_ = duration;
-}
+      has_media_sequence_tag_(args.has_media_sequence_tag) {}
 
 }  // namespace media::hls
diff --git a/media/formats/hls/media_playlist.h b/media/formats/hls/media_playlist.h
index ddf353c..5369086 100644
--- a/media/formats/hls/media_playlist.h
+++ b/media/formats/hls/media_playlist.h
@@ -26,11 +26,11 @@
   // This structure describes information about partial segments in the
   // playlist.
   struct PartialSegmentInfo {
-    // The maximum duration (in seconds) of any partial segment. Each partial
+    // The maximum duration of any partial segment. Each partial
     // segment must be at least 85% of this, except for any where
     // `HasDiscontinuity() == true` or the final partial segment of a parent
     // segment.
-    types::DecimalFloatingPoint target_duration;
+    base::TimeDelta target_duration;
   };
 
   MediaPlaylist(const MediaPlaylist&) = delete;
diff --git a/media/formats/hls/media_playlist_test_builder.h b/media/formats/hls/media_playlist_test_builder.h
index 9fb6ad1..37b8ef2 100644
--- a/media/formats/hls/media_playlist_test_builder.h
+++ b/media/formats/hls/media_playlist_test_builder.h
@@ -13,7 +13,9 @@
 #include "media/formats/hls/media_playlist.h"
 #include "media/formats/hls/media_segment.h"
 #include "media/formats/hls/playlist_test_builder.h"
+#include "media/formats/hls/test_util.h"
 #include "media/formats/hls/types.h"
+#include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 namespace media::hls {
@@ -90,14 +92,16 @@
 inline void HasTargetDuration(base::TimeDelta value,
                               const base::Location& from,
                               const MediaPlaylist& playlist) {
-  EXPECT_EQ(playlist.GetTargetDuration(), value) << from.ToString();
+  EXPECT_TRUE(RoughlyEqual(playlist.GetTargetDuration(), value))
+      << from.ToString();
 }
 
 // Checks that the value of `GetComputedDuration()` matches the given value.
 inline void HasComputedDuration(base::TimeDelta value,
                                 const base::Location& from,
                                 const MediaPlaylist& playlist) {
-  EXPECT_EQ(playlist.GetComputedDuration(), value) << from.ToString();
+  EXPECT_TRUE(RoughlyEqual(playlist.GetComputedDuration(), value))
+      << from.ToString();
 }
 
 // Checks that the value of `GetPartialSegmentInfo()` matches the given value.
@@ -109,8 +113,8 @@
             playlist.GetPartialSegmentInfo().has_value())
       << from.ToString();
   if (partial_segment_info.has_value()) {
-    ASSERT_DOUBLE_EQ(partial_segment_info->target_duration,
-                     playlist.GetPartialSegmentInfo()->target_duration)
+    EXPECT_TRUE(RoughlyEqual(partial_segment_info->target_duration,
+                             playlist.GetPartialSegmentInfo()->target_duration))
         << from.ToString();
   }
 }
@@ -124,10 +128,10 @@
 }
 
 // Checks that the latest media segment has the given duration.
-inline void HasDuration(types::DecimalFloatingPoint duration,
+inline void HasDuration(base::TimeDelta duration,
                         const base::Location& from,
                         const MediaSegment& segment) {
-  EXPECT_DOUBLE_EQ(segment.GetDuration(), duration) << from.ToString();
+  EXPECT_TRUE(RoughlyEqual(segment.GetDuration(), duration)) << from.ToString();
 }
 
 // Checks that the latest media segment has the given media sequence number.
diff --git a/media/formats/hls/media_playlist_unittest.cc b/media/formats/hls/media_playlist_unittest.cc
index 3e759ac6..9089e72c 100644
--- a/media/formats/hls/media_playlist_unittest.cc
+++ b/media/formats/hls/media_playlist_unittest.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "media/formats/hls/media_playlist_test_builder.h"
 #include "media/formats/hls/multivariant_playlist.h"
@@ -132,7 +133,7 @@
   builder.AppendLine("video.ts");
   builder.ExpectAdditionalSegment();
   builder.ExpectSegment(HasDiscontinuity, false);
-  builder.ExpectSegment(HasDuration, 9.2);
+  builder.ExpectSegment(HasDuration, base::Seconds(9.2));
   builder.ExpectSegment(HasUri, GURL("http://localhost/video.ts"));
   builder.ExpectSegment(IsGap, false);
   builder.ExpectSegment(HasMediaSequenceNumber, 0);
@@ -149,7 +150,7 @@
   builder.AppendLine("foo.ts");
   builder.ExpectAdditionalSegment();
   builder.ExpectSegment(HasDiscontinuity, true);
-  builder.ExpectSegment(HasDuration, 9.3);
+  builder.ExpectSegment(HasDuration, base::Seconds(9.3));
   builder.ExpectSegment(IsGap, false);
   builder.ExpectSegment(HasUri, GURL("http://localhost/foo.ts"));
   builder.ExpectSegment(HasMediaSequenceNumber, 1);
@@ -158,7 +159,7 @@
   builder.AppendLine("http://foo/bar.ts");
   builder.ExpectAdditionalSegment();
   builder.ExpectSegment(HasDiscontinuity, false);
-  builder.ExpectSegment(HasDuration, 9.2);
+  builder.ExpectSegment(HasDuration, base::Seconds(9.2));
   builder.ExpectSegment(IsGap, false);
   builder.ExpectSegment(HasUri, GURL("http://foo/bar.ts"));
   builder.ExpectSegment(HasMediaSequenceNumber, 2);
@@ -180,6 +181,41 @@
   builder.ExpectOk();
 }
 
+TEST(HlsMediaPlaylistTest, TotalDuration) {
+  constexpr types::DecimalInteger kLargeDuration =
+      (base::TimeDelta::FiniteMax() / 2.5).InSeconds();
+
+  // Ensure that if we have a playlist large enough where the total duration
+  // overflows `base::TimeDelta`, this is caught.
+  MediaPlaylistTestBuilder builder;
+  builder.AppendLine("#EXTM3U");
+  builder.AppendLine("#EXT-X-TARGETDURATION:" +
+                     base::NumberToString(kLargeDuration));
+  builder.ExpectPlaylist(HasTargetDuration, base::Seconds(kLargeDuration));
+
+  builder.AppendLine("#EXTINF:" + base::NumberToString(kLargeDuration) + ",\t");
+  builder.AppendLine("segment0.ts");
+  builder.ExpectAdditionalSegment();
+  builder.ExpectSegment(HasDuration, base::Seconds(kLargeDuration));
+  builder.ExpectSegment(HasUri, GURL("http://localhost/segment0.ts"));
+
+  builder.AppendLine("#EXTINF:" + base::NumberToString(kLargeDuration) + ",\t");
+  builder.AppendLine("segment1.ts");
+  builder.ExpectAdditionalSegment();
+  builder.ExpectSegment(HasDuration, base::Seconds(kLargeDuration));
+  builder.ExpectSegment(HasUri, GURL("http://localhost/segment1.ts"));
+
+  // These two shouldn't overflow base::TimeDelta
+  builder.ExpectPlaylist(HasComputedDuration,
+                         base::Seconds(kLargeDuration * 2));
+  builder.ExpectOk();
+
+  // But an additional segment would
+  builder.AppendLine("#EXTINF:" + base::NumberToString(kLargeDuration) + ",\t");
+  builder.AppendLine("segment3.ts");
+  builder.ExpectError(ParseStatusCode::kPlaylistOverflowsTimeDelta);
+}
+
 // This test is similar to the `HlsMultivariantPlaylistTest` test of the same
 // name, but due to subtle differences between media playlists and multivariant
 // playlists its difficult to combine them. If new cases are added here that are
@@ -525,12 +561,12 @@
   builder.AppendLine("#EXTINF:10,\t");
   builder.AppendLine("segment0.ts");
   builder.ExpectAdditionalSegment();
-  builder.ExpectSegment(HasDuration, 10);
+  builder.ExpectSegment(HasDuration, base::Seconds(10));
 
   builder.AppendLine("#EXTINF:10,\t");
   builder.AppendLine("segment1.ts");
   builder.ExpectAdditionalSegment();
-  builder.ExpectSegment(HasDuration, 10);
+  builder.ExpectSegment(HasDuration, base::Seconds(10));
 
   builder.ExpectPlaylist(HasComputedDuration, base::Seconds(20));
   builder.ExpectOk();
@@ -1070,26 +1106,30 @@
 
   auto fork = builder;
   fork.AppendLine("#EXT-X-PART-INF:PART-TARGET=0");
-  fork.ExpectPlaylist(HasPartialSegmentInfo,
-                      MediaPlaylist::PartialSegmentInfo{.target_duration = 0});
+  fork.ExpectPlaylist(
+      HasPartialSegmentInfo,
+      MediaPlaylist::PartialSegmentInfo{.target_duration = base::Seconds(0)});
   fork.ExpectOk();
 
   fork = builder;
   fork.AppendLine("#EXT-X-PART-INF:PART-TARGET=1");
-  fork.ExpectPlaylist(HasPartialSegmentInfo,
-                      MediaPlaylist::PartialSegmentInfo{.target_duration = 1});
+  fork.ExpectPlaylist(
+      HasPartialSegmentInfo,
+      MediaPlaylist::PartialSegmentInfo{.target_duration = base::Seconds(1)});
   fork.ExpectOk();
 
   fork = builder;
   fork.AppendLine("#EXT-X-PART-INF:PART-TARGET=1.2");
-  fork.ExpectPlaylist(HasPartialSegmentInfo, MediaPlaylist::PartialSegmentInfo{
-                                                 .target_duration = 1.2});
+  fork.ExpectPlaylist(
+      HasPartialSegmentInfo,
+      MediaPlaylist::PartialSegmentInfo{.target_duration = base::Seconds(1.2)});
   fork.ExpectOk();
 
   fork = builder;
   fork.AppendLine("#EXT-X-PART-INF:PART-TARGET=99.99");
-  fork.ExpectPlaylist(HasPartialSegmentInfo, MediaPlaylist::PartialSegmentInfo{
-                                                 .target_duration = 99.99});
+  fork.ExpectPlaylist(HasPartialSegmentInfo,
+                      MediaPlaylist::PartialSegmentInfo{
+                          .target_duration = base::Seconds(99.99)});
   fork.ExpectOk();
 
   // The EXT-X-PART-INF tag may not appear twice
diff --git a/media/formats/hls/media_segment.cc b/media/formats/hls/media_segment.cc
index 943b999..3c1491f 100644
--- a/media/formats/hls/media_segment.cc
+++ b/media/formats/hls/media_segment.cc
@@ -4,12 +4,13 @@
 
 #include "media/formats/hls/media_segment.h"
 
+#include "base/time/time.h"
 #include "media/formats/hls/types.h"
 #include "url/gurl.h"
 
 namespace media::hls {
 
-MediaSegment::MediaSegment(types::DecimalFloatingPoint duration,
+MediaSegment::MediaSegment(base::TimeDelta duration,
                            types::DecimalInteger media_sequence_number,
                            types::DecimalInteger discontinuity_sequence_number,
                            GURL uri,
diff --git a/media/formats/hls/media_segment.h b/media/formats/hls/media_segment.h
index f3a8b33c..ed3d933 100644
--- a/media/formats/hls/media_segment.h
+++ b/media/formats/hls/media_segment.h
@@ -5,6 +5,7 @@
 #ifndef MEDIA_FORMATS_HLS_MEDIA_SEGMENT_H_
 #define MEDIA_FORMATS_HLS_MEDIA_SEGMENT_H_
 
+#include "base/time/time.h"
 #include "media/base/media_export.h"
 #include "media/formats/hls/types.h"
 #include "url/gurl.h"
@@ -13,7 +14,7 @@
 
 class MEDIA_EXPORT MediaSegment {
  public:
-  MediaSegment(types::DecimalFloatingPoint duration,
+  MediaSegment(base::TimeDelta duration,
                types::DecimalInteger media_sequence_number,
                types::DecimalInteger discontinuity_sequence_number,
                GURL uri,
@@ -27,8 +28,8 @@
   MediaSegment& operator=(const MediaSegment&);
   MediaSegment& operator=(MediaSegment&&);
 
-  // The approximate duration of this media segment in seconds.
-  types::DecimalFloatingPoint GetDuration() const { return duration_; }
+  // The approximate duration of this media segment.
+  base::TimeDelta GetDuration() const { return duration_; }
 
   // Returns the media sequence number of this media segment.
   types::DecimalInteger GetMediaSequenceNumber() const {
@@ -62,7 +63,7 @@
   absl::optional<types::DecimalInteger> GetBitRate() const { return bitrate_; }
 
  private:
-  types::DecimalFloatingPoint duration_;
+  base::TimeDelta duration_;
   types::DecimalInteger media_sequence_number_;
   types::DecimalInteger discontinuity_sequence_number_;
   GURL uri_;
diff --git a/media/formats/hls/parse_status.cc b/media/formats/hls/parse_status.cc
index 9c5ee9d8..86cb36ae 100644
--- a/media/formats/hls/parse_status.cc
+++ b/media/formats/hls/parse_status.cc
@@ -49,6 +49,8 @@
     PARSE_STATUS_CODE_CASE(kDiscontinuityTagBeforeDiscontinuitySequenceTag);
     PARSE_STATUS_CODE_CASE(kByteRangeRequiresOffset);
     PARSE_STATUS_CODE_CASE(kByteRangeInvalid);
+    PARSE_STATUS_CODE_CASE(kValueOverflowsTimeDelta);
+    PARSE_STATUS_CODE_CASE(kPlaylistOverflowsTimeDelta);
   }
 
   NOTREACHED();
diff --git a/media/formats/hls/parse_status.h b/media/formats/hls/parse_status.h
index a1fcc12..9280f3b 100644
--- a/media/formats/hls/parse_status.h
+++ b/media/formats/hls/parse_status.h
@@ -46,6 +46,8 @@
   kDiscontinuityTagBeforeDiscontinuitySequenceTag,
   kByteRangeRequiresOffset,
   kByteRangeInvalid,
+  kValueOverflowsTimeDelta,
+  kPlaylistOverflowsTimeDelta,
 };
 
 struct ParseStatusTraits {
diff --git a/media/formats/hls/tags.cc b/media/formats/hls/tags.cc
index 4d52b51..c26ff19 100644
--- a/media/formats/hls/tags.cc
+++ b/media/formats/hls/tags.cc
@@ -8,6 +8,7 @@
 #include <type_traits>
 #include <utility>
 #include "base/notreached.h"
+#include "base/time/time.h"
 #include "media/formats/hls/items.h"
 #include "media/formats/hls/parse_status.h"
 #include "media/formats/hls/variable_dictionary.h"
@@ -224,13 +225,18 @@
   // Extract duration
   // TODO(crbug.com/1284763): Below version 3 this should be rounded to an
   // integer
-  auto duration = types::ParseDecimalFloatingPoint(duration_str);
-  if (duration.has_error()) {
+  auto duration_result = types::ParseDecimalFloatingPoint(duration_str);
+  if (duration_result.has_error()) {
     return ParseStatus(ParseStatusCode::kMalformedTag)
-        .AddCause(std::move(duration).error());
+        .AddCause(std::move(duration_result).error());
+  }
+  const auto duration = base::Seconds(std::move(duration_result).value());
+
+  if (duration.is_max()) {
+    return ParseStatusCode::kValueOverflowsTimeDelta;
   }
 
-  return InfTag{.duration = std::move(duration).value(), .title = title_str};
+  return InfTag{.duration = duration, .title = title_str};
 }
 
 ParseStatus::Or<XIndependentSegmentsTag> XIndependentSegmentsTag::Parse(
@@ -459,7 +465,23 @@
 }
 
 ParseStatus::Or<XTargetDurationTag> XTargetDurationTag::Parse(TagItem tag) {
-  return ParseDecimalIntegerTag(tag, &XTargetDurationTag::duration);
+  DCHECK(tag.GetName() == ToTagName(XTargetDurationTag::kName));
+  if (!tag.GetContent().has_value()) {
+    return ParseStatusCode::kMalformedTag;
+  }
+
+  auto duration_result = types::ParseDecimalInteger(tag.GetContent().value());
+  if (duration_result.has_error()) {
+    return ParseStatus(ParseStatusCode::kMalformedTag)
+        .AddCause(std::move(duration_result).error());
+  }
+
+  auto duration = base::Seconds(std::move(duration_result).value());
+  if (duration.is_max()) {
+    return ParseStatusCode::kValueOverflowsTimeDelta;
+  }
+
+  return XTargetDurationTag{.duration = duration};
 }
 
 ParseStatus::Or<XPartInfTag> XPartInfTag::Parse(TagItem tag) {
@@ -478,22 +500,27 @@
         .AddCause(std::move(map_result));
   }
 
-  XPartInfTag out;
-
   // Extract the 'PART-TARGET' attribute
+  base::TimeDelta part_target;
   if (map.HasValue(XPartInfTagAttribute::kPartTarget)) {
-    auto target_duration = types::ParseDecimalFloatingPoint(
+    auto result = types::ParseDecimalFloatingPoint(
         map.GetValue(XPartInfTagAttribute::kPartTarget));
-    if (target_duration.has_error()) {
+
+    if (result.has_error()) {
       return ParseStatus(ParseStatusCode::kMalformedTag)
-          .AddCause(std::move(target_duration).error());
+          .AddCause(std::move(result).error());
     }
-    out.target_duration = std::move(target_duration).value();
+
+    part_target = base::Seconds(std::move(result).value());
+
+    if (part_target.is_max()) {
+      return ParseStatusCode::kValueOverflowsTimeDelta;
+    }
   } else {
     return ParseStatusCode::kMalformedTag;
   }
 
-  return out;
+  return XPartInfTag{.target_duration = part_target};
 }
 
 ParseStatus::Or<XMediaSequenceTag> XMediaSequenceTag::Parse(TagItem tag) {
diff --git a/media/formats/hls/tags.h b/media/formats/hls/tags.h
index a0aa37d..720d81c 100644
--- a/media/formats/hls/tags.h
+++ b/media/formats/hls/tags.h
@@ -5,6 +5,7 @@
 #ifndef MEDIA_FORMATS_HLS_TAGS_H_
 #define MEDIA_FORMATS_HLS_TAGS_H_
 
+#include "base/time/time.h"
 #include "media/base/media_export.h"
 #include "media/formats/hls/parse_status.h"
 #include "media/formats/hls/tag_name.h"
@@ -61,8 +62,8 @@
   static constexpr auto kName = MediaPlaylistTagName::kInf;
   static ParseStatus::Or<InfTag> Parse(TagItem);
 
-  // Target duration of the media segment, in seconds.
-  types::DecimalFloatingPoint duration;
+  // Target duration of the media segment.
+  base::TimeDelta duration;
 
   // Human-readable title of the media segment.
   SourceString title;
@@ -159,11 +160,11 @@
   static constexpr auto kName = MediaPlaylistTagName::kXTargetDuration;
   static ParseStatus::Or<XTargetDurationTag> Parse(TagItem);
 
-  // The upper bound on the duration (in seconds) of all media segments in the
+  // The upper bound on the duration of all media segments in the
   // media playlist. The EXTINF duration of each Media Segment in a Playlist
   // file, when rounded to the nearest integer, MUST be less than or equal to
   // this duration.
-  types::DecimalInteger duration;
+  base::TimeDelta duration;
 };
 
 // Represents the contents of the #EXT-PART-INF tag.
@@ -172,7 +173,7 @@
   static ParseStatus::Or<XPartInfTag> Parse(TagItem);
 
   // This value indicates the target duration for partial media segments.
-  types::DecimalFloatingPoint target_duration;
+  base::TimeDelta target_duration;
 };
 
 // Represents the contents of the #EXT-X-MEDIA-SEQUENCE tag.
diff --git a/media/formats/hls/tags_unittest.cc b/media/formats/hls/tags_unittest.cc
index 55da16d6..dbeefd5 100644
--- a/media/formats/hls/tags_unittest.cc
+++ b/media/formats/hls/tags_unittest.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/location.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "media/formats/hls/items.h"
 #include "media/formats/hls/parse_status.h"
@@ -20,6 +21,12 @@
 
 namespace {
 
+// Returns the maximum whole quantity of seconds that can be represented by this
+// implementation.
+types::DecimalInteger MaxSeconds() {
+  return base::TimeDelta::FiniteMax().InSeconds();
+}
+
 template <typename T>
 void ErrorTest(absl::optional<base::StringPiece> content,
                ParseStatusCode expected_status,
@@ -125,7 +132,6 @@
   ErrorTest<T>("-.5", ParseStatusCode::kMalformedTag);
   ErrorTest<T>(".5", ParseStatusCode::kMalformedTag);
   ErrorTest<T>("0.5", ParseStatusCode::kMalformedTag);
-  ErrorTest<T>("9999999999999999999999", ParseStatusCode::kMalformedTag);
   ErrorTest<T>("one", ParseStatusCode::kMalformedTag);
   ErrorTest<T>(" 1 ", ParseStatusCode::kMalformedTag);
   ErrorTest<T>("1,", ParseStatusCode::kMalformedTag);
@@ -139,8 +145,6 @@
   EXPECT_EQ(tag.*field, 10u);
   tag = OkTest<T>("14");
   EXPECT_EQ(tag.*field, 14u);
-  tag = OkTest<T>("999999999999999999");
-  EXPECT_EQ(tag.*field, 999999999999999999u);
 }
 
 VariableDictionary CreateBasicDictionary(
@@ -219,26 +223,26 @@
   RunTagIdenficationTest<InfTag>("#EXTINF:123,\t\n", "123,\t");
 
   // Test some valid tags
-  auto tag = OkTest<InfTag>("1234,");
-  EXPECT_EQ(tag.duration, 1234.0);
+  auto tag = OkTest<InfTag>("123,");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(123.0)));
   EXPECT_EQ(tag.title.Str(), "");
 
-  tag = OkTest<InfTag>("1.234,");
-  EXPECT_EQ(tag.duration, 1.234);
+  tag = OkTest<InfTag>("1.23,");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(1.23)));
   EXPECT_EQ(tag.title.Str(), "");
 
   // The spec implies that whitespace characters like this usually aren't
   // permitted, but "\t" is a common occurrence for the title value.
   tag = OkTest<InfTag>("99.5,\t");
-  EXPECT_EQ(tag.duration, 99.5);
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(99.5)));
   EXPECT_EQ(tag.title.Str(), "\t");
 
   tag = OkTest<InfTag>("9.5,,,,");
-  EXPECT_EQ(tag.duration, 9.5);
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(9.5)));
   EXPECT_EQ(tag.title.Str(), ",,,");
 
   tag = OkTest<InfTag>("12,asdfsdf   ");
-  EXPECT_EQ(tag.duration, 12.0);
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(12.0)));
   EXPECT_EQ(tag.title.Str(), "asdfsdf   ");
 
   // Test some invalid tags
@@ -248,6 +252,12 @@
   ErrorTest<InfTag>("-123,", ParseStatusCode::kMalformedTag);
   ErrorTest<InfTag>("123", ParseStatusCode::kMalformedTag);
   ErrorTest<InfTag>("asdf,", ParseStatusCode::kMalformedTag);
+
+  // Test max value
+  tag = OkTest<InfTag>(base::NumberToString(MaxSeconds()) + ",\t");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(MaxSeconds())));
+  ErrorTest<InfTag>(base::NumberToString(MaxSeconds() + 1) + ",\t",
+                    ParseStatusCode::kValueOverflowsTimeDelta);
 }
 
 TEST(HlsTagsTest, ParseXIndependentSegmentsTag) {
@@ -461,7 +471,32 @@
 TEST(HlsTagsTest, ParseXTargetDurationTag) {
   RunTagIdenficationTest<XTargetDurationTag>("#EXT-X-TARGETDURATION:10\n",
                                              "10");
-  RunDecimalIntegerTagTest(&XTargetDurationTag::duration);
+
+  // Content must be a valid decimal-integer
+  ErrorTest<XTargetDurationTag>(absl::nullopt, ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("-1", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("1.5", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>(" 1", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("1 ", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("one", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("{$ONE}", ParseStatusCode::kMalformedTag);
+  ErrorTest<XTargetDurationTag>("1,", ParseStatusCode::kMalformedTag);
+
+  auto tag = OkTest<XTargetDurationTag>("0");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(0)));
+
+  tag = OkTest<XTargetDurationTag>("1");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(1)));
+
+  tag = OkTest<XTargetDurationTag>("99");
+  EXPECT_TRUE(RoughlyEqual(tag.duration, base::Seconds(99)));
+
+  // Test max value
+  tag = OkTest<XTargetDurationTag>(base::NumberToString(MaxSeconds()));
+  EXPECT_EQ(tag.duration, base::Seconds(MaxSeconds()));
+  ErrorTest<XTargetDurationTag>(base::NumberToString(MaxSeconds() + 1),
+                                ParseStatusCode::kValueOverflowsTimeDelta);
 }
 
 TEST(HlsTagsTest, ParseXMediaSequenceTag) {
@@ -518,15 +553,21 @@
                          ParseStatusCode::kMalformedTag);
 
   auto tag = OkTest<XPartInfTag>("PART-TARGET=1.2");
-  EXPECT_DOUBLE_EQ(tag.target_duration, 1.2);
+  EXPECT_TRUE(RoughlyEqual(tag.target_duration, base::Seconds(1.2)));
   tag = OkTest<XPartInfTag>("PART-TARGET=1");
-  EXPECT_DOUBLE_EQ(tag.target_duration, 1);
+  EXPECT_TRUE(RoughlyEqual(tag.target_duration, base::Seconds(1)));
   tag = OkTest<XPartInfTag>("PART-TARGET=0");
-  EXPECT_DOUBLE_EQ(tag.target_duration, 0);
-  tag = OkTest<XPartInfTag>("PART-TARGET=99999999.99");
-  EXPECT_DOUBLE_EQ(tag.target_duration, 99999999.99);
+  EXPECT_TRUE(RoughlyEqual(tag.target_duration, base::Seconds(0)));
   tag = OkTest<XPartInfTag>("FOO=BAR,PART-TARGET=100,BAR=BAZ");
-  EXPECT_DOUBLE_EQ(tag.target_duration, 100);
+  EXPECT_TRUE(RoughlyEqual(tag.target_duration, base::Seconds(100)));
+
+  // Test the max value
+  tag =
+      OkTest<XPartInfTag>("PART-TARGET=" + base::NumberToString(MaxSeconds()));
+  EXPECT_TRUE(RoughlyEqual(tag.target_duration, base::Seconds(MaxSeconds())));
+  ErrorTest<XPartInfTag>(
+      "PART-TARGET=" + base::NumberToString(MaxSeconds() + 1),
+      ParseStatusCode::kValueOverflowsTimeDelta);
 }
 
 }  // namespace media::hls
diff --git a/media/formats/hls/test_util.h b/media/formats/hls/test_util.h
index fdc5506..17268ee 100644
--- a/media/formats/hls/test_util.h
+++ b/media/formats/hls/test_util.h
@@ -6,8 +6,11 @@
 #define MEDIA_FORMATS_HLS_TEST_UTIL_H_
 
 #include "base/strings/string_piece.h"
+#include "base/time/time.h"
 #include "media/formats/hls/source_string.h"
 #include "media/formats/hls/types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace media::hls {
 
@@ -21,6 +24,37 @@
   return types::ByteRange::Validate(length, offset).value();
 }
 
+// Helper for comparing base::TimeDelta values which may have some
+// floating-point imprecision.
+inline testing::AssertionResult RoughlyEqual(
+    base::TimeDelta lhs,
+    base::TimeDelta rhs,
+    base::TimeDelta epsilon = base::Milliseconds(1)) {
+  if (lhs + epsilon >= rhs && lhs - epsilon <= rhs) {
+    return testing::AssertionSuccess();
+  }
+
+  return testing::AssertionFailure()
+         << lhs << " != " << rhs << " +- " << epsilon;
+}
+
+inline testing::AssertionResult RoughlyEqual(
+    absl::optional<base::TimeDelta> lhs,
+    absl::optional<base::TimeDelta> rhs,
+    base::TimeDelta epsilon = base::Milliseconds(1)) {
+  if (!lhs.has_value() && !rhs.has_value()) {
+    return testing::AssertionSuccess();
+  }
+  if (lhs.has_value() && !rhs.has_value()) {
+    return testing::AssertionFailure() << lhs.value() << " != absl::nullopt";
+  }
+  if (!lhs.has_value() && rhs.has_value()) {
+    return testing::AssertionFailure() << "absl::nullopt != " << rhs.value();
+  }
+
+  return RoughlyEqual(lhs.value(), rhs.value(), epsilon);
+}
+
 }  // namespace media::hls
 
 #endif
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc
index 30329b4f..ee3e0ab0 100644
--- a/media/formats/mp4/track_run_iterator.cc
+++ b/media/formats/mp4/track_run_iterator.cc
@@ -500,7 +500,10 @@
           // If we don't have a per-sample IV, get the constant IV.
           bool is_encrypted = index == 0 ? track_encryption->is_encrypted
                                          : info_entry->is_encrypted;
-#if BUILDFLAG(IS_CHROMECAST)
+
+          // TODO(crbug.com/1336055): Investigate if this is a hardware or
+          // cast-related limitation.
+#if BUILDFLAG(IS_CASTOS)
           // On Chromecast, we only support setting the pattern values in the
           // 'tenc' box for the track (not varying on per sample group basis).
           // Thus we need to verify that the settings in the sample group
@@ -519,7 +522,7 @@
                                 "sample group does not match that in the tenc "
                                 "box . This is not currently supported.");
           }
-#endif  // BUILDFLAG(IS_CHROMECAST)
+#endif  // BUILDFLAG(IS_CASTOS)
           if (is_encrypted && !iv_size) {
             const uint8_t constant_iv_size =
                 index == 0 ? track_encryption->default_constant_iv_size
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index bb2ff07..da3ea5a 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -8,9 +8,8 @@
 declare_args() {
   # Indicates if X11 VA-API-based hardware acceleration is to be used.
   # See also the comment near the |use_vaapi| arg.
-  use_vaapi_x11 =
-      is_linux && ozone_platform_x11 && !is_chromecast && !is_chromeos_lacros &&
-      (target_cpu == "x86" || target_cpu == "x64")
+  use_vaapi_x11 = is_linux && ozone_platform_x11 &&
+                  (target_cpu == "x86" || target_cpu == "x64") && !is_castos
 }
 
 declare_args() {
diff --git a/media/media_options.gni b/media/media_options.gni
index e7d0b0b..dd6fb26 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -13,6 +13,9 @@
 import("//third_party/libaom/options.gni")
 import("//third_party/libgav1/options.gni")
 
+# This flag sets defaults for the current generation of cast devices.
+is_cast_media_device = is_castos || is_cast_android
+
 declare_args() {
   # Allows distributions to link pulseaudio directly (DT_NEEDED) instead of
   # using dlopen. This helps with automated detection of ABI mismatches and
@@ -47,35 +50,48 @@
   # Enables AC3/EAC3 audio demuxing. This is enabled only on Chromecast, since
   # it only provides demuxing, and is only useful for AC3/EAC3 audio
   # pass-through to HDMI sink on Chromecast.
-  enable_platform_ac3_eac3_audio = proprietary_codecs && is_chromecast
+  enable_platform_ac3_eac3_audio = proprietary_codecs && is_cast_media_device
 
-  enable_platform_mpeg_h_audio = proprietary_codecs && is_chromecast
+  enable_platform_mpeg_h_audio = proprietary_codecs && is_cast_media_device
 
   # Enables DTS/DTSX audio handling in chromium. This includes demuxing,
   # on-device decoding and bitstream passthrough as supported by device.
   enable_platform_dts_audio = false
 
+  # TODO(crbug.com/1330636): Remove the `is_fuchsia` condition once fuchsia
+  # builds set enable_cast_receiver.
   enable_mse_mpeg2ts_stream_parser =
-      proprietary_codecs && (is_chromecast || is_fuchsia || use_fuzzing_engine)
+      proprietary_codecs &&
+      (enable_cast_receiver || is_fuchsia || use_fuzzing_engine)
 
   # Enable Dolby Vision demuxing. Enable by default for Chromecast. Actual
   # decoding must be provided by the platform. Note some Dolby Vision profiles
   # which are encoded using HEVC require |enable_platform_hevc| to be enabled.
-  enable_platform_dolby_vision = proprietary_codecs && is_chromecast
+  #
+  # TODO(crbug.com/1336055): Revisit the default value for this setting as it
+  # applies to video-capable devices.
+  enable_platform_dolby_vision = proprietary_codecs && is_cast_media_device
 
   # Enable HLS with SAMPLE-AES decryption.
-  enable_hls_sample_aes = proprietary_codecs && (is_chromecast || is_fuchsia)
+  #
+  # TODO(crbug.com/1330636): Remove the `is_fuchsia` condition once fuchsia
+  # builds set enable_cast_receiver.
+  enable_hls_sample_aes =
+      proprietary_codecs && (enable_cast_receiver || is_fuchsia)
 
   # Enable logging override, e.g. enable DVLOGs through level 2 at build time.
   # On Chromecast, these are logged as INFO.
   # On Fuchsia, these are logged as VLOGs.
-  enable_logging_override = is_chromecast || is_fuchsia
+  enable_logging_override = is_cast_media_device || is_fuchsia
 
   enable_dav1d_decoder = !is_ios
 
   # Enable browser managed persistent metadata storage for EME persistent
   # session and persistent usage record session.
-  enable_media_drm_storage = is_android || is_chromecast
+  #
+  # TODO(crbug.com/1330636): Remove the Fuchsia `is_chromecast` condition.
+  enable_media_drm_storage =
+      is_android || is_castos || (is_fuchsia && is_chromecast)
 
   # Enable HLS manifest parser and demuxer.
   enable_hls_demuxer = false
@@ -97,11 +113,32 @@
   # Enable HEVC/H265 demuxing. Actual decoding must be provided by the
   # platform.
   # TODO(b/194429120): Enable this for Lacros builds.
+  # TODO(crbug.com/1336055): Revisit the default value for this setting as it
+  # applies to video-capable devices.
   enable_platform_hevc =
-      proprietary_codecs && (is_chromecast || enable_hevc_parser_and_hw_decoder)
+      proprietary_codecs &&
+      (enable_hevc_parser_and_hw_decoder || is_cast_media_device)
 }
 
 assert(
+    !enable_platform_ac3_eac3_audio || proprietary_codecs,
+    "proprietary_codecs=true is required for enable_platform_ac3_eac3_audio=true.")
+assert(
+    !enable_platform_mpeg_h_audio || proprietary_codecs,
+    "proprietary_codecs=true is required for enable_platform_mpeg_h_audio=true.")
+assert(
+    !enable_mse_mpeg2ts_stream_parser || proprietary_codecs,
+    "proprietary_codecs=true is required for enable_mse_mpeg2ts_stream_parser=true.")
+assert(
+    !enable_platform_dolby_vision || proprietary_codecs,
+    "proprietary_codecs=true is required for enable_platform_dolby_vision=true.")
+assert(!enable_hls_sample_aes || proprietary_codecs,
+       "proprietary_codecs=true is required for enable_hls_sample_aes=true.")
+assert(
+    !enable_platform_dts_audio || proprietary_codecs,
+    "proprietary_codecs=true is required for enable_platform_dts_audio=true.")
+
+assert(
     !enable_hls_sample_aes || enable_mse_mpeg2ts_stream_parser,
     "enable_mse_mpeg2ts_stream_parser=true is required for enable_hls_sample_aes=true.")
 
@@ -124,10 +161,14 @@
   # Enables runtime selection of ALSA library for audio.
   use_alsa = false
 
-  # Alsa should be used on non-Android, non-Mac POSIX systems (excluding CastOS
-  # video builds).
+  # Alsa should be used on all non-Android, non-Mac POSIX systems - with the
+  # exception of CastOS desktop builds.
+  #
+  # TODO(crbug.com/1336055): Remove legacy target_cpu hack used for targeting
+  # desktop Chromecast builds.
   if (is_posix && !is_android && !is_mac &&
-      (!is_castos || is_cast_audio_only)) {
+      (!is_castos || (target_cpu == "x86" || target_cpu == "x64") ||
+       is_cast_audio_only)) {
     use_alsa = true
 
     # Pulse is not supported on Chromecast platforms.
@@ -138,7 +179,7 @@
     # TODO(crbug.com/986021): We shouldn't have to do this, but it's unclear why
     # our test bots are hanging and all of the ones that don't hang just fall
     # back to ALSA after a connection error anyways.
-    if (!use_cras && !is_chromecast && !is_asan && !is_tsan) {
+    if (!use_cras && !is_castos && !is_asan && !is_tsan) {
       use_pulseaudio = true
     }
   }
@@ -159,7 +200,7 @@
   # media/cdm/api/content_decryption_module.h. If true, the actually library CDM
   # will be hosted in the mojo CDM service running in the CDM (utility) process.
   # Used for all desktop platforms except Fuchsia (crbug.com/1265618).
-  enable_library_cdms = toolkit_views && !is_fuchsia && !is_chromecast
+  enable_library_cdms = toolkit_views && !is_fuchsia && !is_castos
 }
 
 declare_args() {
@@ -189,7 +230,7 @@
 _default_mojo_media_services = []
 _default_mojo_media_host = ""
 
-if (is_chromecast) {
+if (is_cast_media_device) {
   _default_mojo_media_services = cast_mojo_media_services
   _default_mojo_media_host = cast_mojo_media_host
 } else if (is_android) {
@@ -253,7 +294,7 @@
   # This switch defines whether the Media Remoting implementation will be built.
   # When enabled, media is allowed to be renderer and played back on remote
   # devices when the tab is being casted and other conditions are met.
-  enable_media_remoting = !is_chromecast && !is_ios
+  enable_media_remoting = !is_cast_media_device && !is_ios
 }
 
 declare_args() {
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn
index d36f580c..f65c4b2 100644
--- a/media/mojo/mojom/BUILD.gn
+++ b/media/mojo/mojom/BUILD.gn
@@ -61,7 +61,9 @@
     sources += [ "speech_recognition_service.mojom" ]
   }
 
-  if (is_chromecast) {
+  # TODO(crbug.com/1293520): Revisit this after the cast renderer has been
+  # deprecated and removed.
+  if (is_castos || is_cast_android) {
     sources += [ "cast_application_media_info_manager.mojom" ]
   }
 
diff --git a/media/mojo/services/media_metrics_provider.cc b/media/mojo/services/media_metrics_provider.cc
index 62d2f6a..e98ae88 100644
--- a/media/mojo/services/media_metrics_provider.cc
+++ b/media/mojo/services/media_metrics_provider.cc
@@ -22,9 +22,9 @@
 
 #if !BUILDFLAG(IS_ANDROID)
 #include "media/filters/decrypting_video_decoder.h"
-#endif  // !BUILDFLAG(IS_ANDROID)
+#endif
 
-#if BUILDFLAG(IS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && BUILDFLAG(IS_ANDROID))
+#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CAST_ANDROID)
 #include "media/mojo/services/playback_events_recorder.h"
 #endif
 
@@ -350,7 +350,7 @@
 
 void MediaMetricsProvider::AcquirePlaybackEventsRecorder(
     mojo::PendingReceiver<mojom::PlaybackEventsRecorder> receiver) {
-#if BUILDFLAG(IS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && BUILDFLAG(IS_ANDROID))
+#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_CAST_ANDROID)
   PlaybackEventsRecorder::Create(std::move(receiver));
 #endif
 }
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc
index 586fea2..24d694d0 100644
--- a/media/webrtc/audio_processor.cc
+++ b/media/webrtc/audio_processor.cc
@@ -39,7 +39,7 @@
 
 int GetCaptureBufferSize(bool need_webrtc_processing,
                          const AudioParameters device_format) {
-#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CAST_ANDROID)
   // TODO(henrika): Re-evaluate whether to use same logic as other platforms.
   // https://crbug.com/638081
   return 2 * device_format.sample_rate() / 100;
@@ -579,14 +579,16 @@
     const AudioProcessingSettings& settings) {
   const bool need_webrtc_audio_processing =
       settings.NeedWebrtcAudioProcessing();
+  // TODO(crbug.com/1336055): Investigate why chromecast devices need special
+  // logic here.
   const int output_sample_rate =
       need_webrtc_audio_processing ?
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
                                    std::min(media::kAudioProcessingSampleRateHz,
                                             input_format.sample_rate())
 #else
                                    media::kAudioProcessingSampleRateHz
-#endif  // BUILDFLAG(IS_CHROMECAST)
+#endif
                                    : input_format.sample_rate();
 
   media::ChannelLayout output_channel_layout;
diff --git a/media/webrtc/audio_processor_test.cc b/media/webrtc/audio_processor_test.cc
index 2cb5a35..296ea8d2 100644
--- a/media/webrtc/audio_processor_test.cc
+++ b/media/webrtc/audio_processor_test.cc
@@ -38,16 +38,18 @@
 namespace media {
 namespace {
 
+// TODO(crbug.com/1334991): Clarify WebRTC audio processing support for 96 kHz
+// input.
 static const int kSupportedSampleRates[] = {8000,
                                             16000,
                                             22050,
                                             32000,
                                             44100,
                                             48000
-#if BUILDFLAG(IS_CHROMECAST)
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
                                             ,
                                             96000
-#endif  // BUILDFLAG(IS_CHROMECAST)
+#endif
 };
 
 using MockProcessedCaptureCallback =
diff --git a/media/webrtc/helpers.cc b/media/webrtc/helpers.cc
index 57a50bb..e2c2bc9 100644
--- a/media/webrtc/helpers.cc
+++ b/media/webrtc/helpers.cc
@@ -25,11 +25,14 @@
 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
 
 // The analog gain controller can only be disabled on Chromecast.
-#if BUILDFLAG(IS_CHROMECAST)
+//
+// TODO(crbug.com/1336055): kAllowToDisableAnalogAgc should be removed once AGC2
+// is fully launched.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 constexpr bool kAllowToDisableAnalogAgc = true;
 #else
 constexpr bool kAllowToDisableAnalogAgc = false;
-#endif  // BUILDFLAG(IS_CHROMECAST)
+#endif
 
 // AGC1 mode.
 using Agc1Mode = webrtc::AudioProcessing::Config::GainController1::Mode;
diff --git a/media/webrtc/helpers_unittests.cc b/media/webrtc/helpers_unittests.cc
index 4b3bd1a..1d8970e6 100644
--- a/media/webrtc/helpers_unittests.cc
+++ b/media/webrtc/helpers_unittests.cc
@@ -117,7 +117,10 @@
   auto config = CreateApmGetConfig(
       /*settings=*/{.automatic_gain_control = false,
                     .experimental_automatic_gain_control = false});
-#if BUILDFLAG(IS_CHROMECAST)
+
+// TODO(crbug.com/1336055): Make this check non-conditional following the launch
+// of AGC2.
+#if BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
   // Override the default config since on Chromecast AGC1 is explicitly
   // disabled.
   auto expected_config = kDefaultApmConfig.gain_controller1;
@@ -125,7 +128,7 @@
   EXPECT_EQ(config.gain_controller1, expected_config);
 #else
   EXPECT_EQ(config.gain_controller1, kDefaultApmConfig.gain_controller1);
-#endif
+#endif  // BUILDFLAG(IS_CASTOS) || BUILDFLAG(IS_CAST_ANDROID)
 }
 
 TEST(CreateWebRtcAudioProcessingModuleTest,
diff --git a/net/der/parse_values.cc b/net/der/parse_values.cc
index caab98e..aac0b25 100644
--- a/net/der/parse_values.cc
+++ b/net/der/parse_values.cc
@@ -450,7 +450,7 @@
     memcpy(in_32bit.data(), in.UnsafeData(), in.Length());
   for (const uint32_t c : in_32bit) {
     // UniversalString is UCS-4 in big-endian order.
-    auto codepoint = static_cast<base_icu::UChar32>(base::NetToHost32(c));
+    uint32_t codepoint = base::NetToHost32(c);
     if (!CBU_IS_UNICODE_CHAR(codepoint))
       return false;
 
@@ -469,7 +469,7 @@
     memcpy(in_16bit.data(), in.UnsafeData(), in.Length());
   for (const uint16_t c : in_16bit) {
     // BMPString is UCS-2 in big-endian order.
-    base_icu::UChar32 codepoint = base::NetToHost16(c);
+    uint32_t codepoint = base::NetToHost16(c);
 
     // BMPString only supports codepoints in the Basic Multilingual Plane;
     // surrogates are not allowed. CBU_IS_UNICODE_CHAR excludes the surrogate
diff --git a/net/test/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTestUtil.java b/net/test/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTestUtil.java
index 77f5b4a..5523373 100644
--- a/net/test/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTestUtil.java
+++ b/net/test/android/javatests/src/org/chromium/net/AndroidNetworkLibraryTestUtil.java
@@ -4,7 +4,7 @@
 
 package org.chromium.net;
 
-import org.chromium.base.annotations.CalledByNativeForTesting;
+import org.chromium.base.annotations.CalledByNative;
 
 /**
  * Utility functions for testing features implemented in AndroidNetworkLibrary.
@@ -15,7 +15,7 @@
     /**
      * Helper for tests that simulates an app controlling cleartext traffic on M and newer.
      */
-    @CalledByNativeForTesting
+    @CalledByNative
     public static void setUpSecurityPolicyForTesting(boolean cleartextPermitted) {
         sDefaultCleartextCheckCount = 0;
         sPerHostCleartextCheckCount = 0;
@@ -37,12 +37,12 @@
                 });
     }
 
-    @CalledByNativeForTesting
+    @CalledByNative
     private static int getPerHostCleartextCheckCount() {
         return sPerHostCleartextCheckCount;
     }
 
-    @CalledByNativeForTesting
+    @CalledByNative
     private static int getDefaultCleartextCheckCount() {
         return sDefaultCleartextCheckCount;
     }
diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc
index bdff06f..e20bb88e 100644
--- a/remoting/host/basic_desktop_environment.cc
+++ b/remoting/host/basic_desktop_environment.cc
@@ -122,8 +122,9 @@
     DesktopDisplayInfoMonitor::Callback callback =
         std::move(converting_callback).Then(std::move(video_layout_callback));
 
-    display_info_monitor_ = std::make_unique<DesktopDisplayInfoMonitor>(
-        ui_task_runner_, std::move(callback));
+    display_info_monitor_ =
+        std::make_unique<DesktopDisplayInfoMonitor>(ui_task_runner_);
+    display_info_monitor_->AddCallback(std::move(callback));
   }
   return display_info_monitor_.get();
 }
diff --git a/remoting/host/desktop_display_info_monitor.cc b/remoting/host/desktop_display_info_monitor.cc
index 2e852ce..e06a1a77 100644
--- a/remoting/host/desktop_display_info_monitor.cc
+++ b/remoting/host/desktop_display_info_monitor.cc
@@ -10,7 +10,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "remoting/base/logging.h"
-#include "remoting/host/client_session_control.h"
+#include "remoting/proto/control.pb.h"
 
 namespace remoting {
 
@@ -26,10 +26,8 @@
 }  // namespace
 
 DesktopDisplayInfoMonitor::DesktopDisplayInfoMonitor(
-    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-    Callback callback)
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner)
     : ui_task_runner_(ui_task_runner),
-      callback_(callback),
       desktop_display_info_loader_(DesktopDisplayInfoLoader::Create()) {
   // The loader must be initialized and used on the UI thread (though it can be
   // created on any thread).
@@ -59,9 +57,20 @@
   }
 }
 
+void DesktopDisplayInfoMonitor::AddCallback(
+    DesktopDisplayInfoMonitor::Callback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // Adding callbacks is not supported after displays have already been
+  // loaded.
+  DCHECK_EQ(desktop_display_info_.NumDisplays(), 0);
+
+  callback_list_.AddUnsafe(std::move(callback));
+}
+
 void DesktopDisplayInfoMonitor::QueryDisplayInfoImpl() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (callback_) {
+  if (!callback_list_.empty()) {
     ui_task_runner_->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(&DesktopDisplayInfoLoader::GetCurrentDisplayInfo,
@@ -74,12 +83,12 @@
 void DesktopDisplayInfoMonitor::OnDisplayInfoLoaded(DesktopDisplayInfo info) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (!callback_ || desktop_display_info_ == info) {
+  if (callback_list_.empty() || desktop_display_info_ == info) {
     return;
   }
 
   desktop_display_info_ = std::move(info);
-  callback_.Run(desktop_display_info_);
+  callback_list_.Notify(desktop_display_info_);
 }
 
 }  // namespace remoting
diff --git a/remoting/host/desktop_display_info_monitor.h b/remoting/host/desktop_display_info_monitor.h
index a0a6a8f..86a5c0a 100644
--- a/remoting/host/desktop_display_info_monitor.h
+++ b/remoting/host/desktop_display_info_monitor.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/callback.h"
+#include "base/callback_list.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
@@ -22,7 +23,7 @@
 namespace remoting {
 
 // This class regularly queries the OS for any changes to the multi-monitor
-// display configuration, and reports any changes to the ClientSession.
+// display configuration, and reports any changes to the registered callbacks.
 // This class ensures that the DisplayInfo is fetched on the UI thread, which
 // may be different from the calling thread. This is helpful on platforms where
 // REMOTING_MULTI_PROCESS == false, allowing this class to be used on the
@@ -30,11 +31,11 @@
 // the Desktop process.
 class DesktopDisplayInfoMonitor {
  public:
-  using Callback = base::RepeatingCallback<void(const DesktopDisplayInfo&)>;
+  using CallbackSignature = void(const DesktopDisplayInfo&);
+  using Callback = base::RepeatingCallback<CallbackSignature>;
 
-  DesktopDisplayInfoMonitor(
-      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-      Callback callback);
+  explicit DesktopDisplayInfoMonitor(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
 
   DesktopDisplayInfoMonitor(const DesktopDisplayInfoMonitor&) = delete;
   DesktopDisplayInfoMonitor& operator=(const DesktopDisplayInfoMonitor&) =
@@ -43,11 +44,11 @@
   virtual ~DesktopDisplayInfoMonitor();
 
   // Begins continuous monitoring for changes. Any changes to the monitor layout
-  // will be reported to the ClientSessionControl.
+  // will be reported to the registered callbacks.
   void Start();
 
   // Queries the OS immediately for the current monitor layout and reports any
-  // changed display info to the ClientSessionControl. If this instance is
+  // changed display info to the registered callbacks. If this instance is
   // associated with only one DesktopCapturerProxy, this method could be used to
   // query the display info after each captured frame. If there are multiple
   // capturers all linked to this instance, it doesn't make sense to query after
@@ -55,6 +56,12 @@
   // calls to QueryDisplayInfo() will have no effect.
   void QueryDisplayInfo();
 
+  // Adds a callback to be notified of display-info changes. Callbacks must not
+  // be added after calling Start() or QueryDisplayInfo(). This implementation
+  // does not return a base::CallbackListSubscription, so |callback| must either
+  // outlive this object, or be bound to a suitable WeakPtr.
+  void AddCallback(Callback callback);
+
  private:
   void QueryDisplayInfoImpl();
   void OnDisplayInfoLoaded(DesktopDisplayInfo info);
@@ -63,8 +70,9 @@
 
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
 
-  // Callback which receives DesktopDisplayInfo updates.
-  Callback callback_ GUARDED_BY_CONTEXT(sequence_checker_);
+  // Callbacks which receive DesktopDisplayInfo updates.
+  base::RepeatingCallbackList<CallbackSignature> callback_list_
+      GUARDED_BY_CONTEXT(sequence_checker_);
 
   // Contains the most recently gathered info about the desktop displays.
   DesktopDisplayInfo desktop_display_info_
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc
index b10a860..a895fb9 100644
--- a/remoting/host/input_injector_x11.cc
+++ b/remoting/host/input_injector_x11.cc
@@ -352,7 +352,7 @@
   pressed_keys_.clear();
 
   const std::string text = event.text();
-  for (size_t index = 0; index < text.size(); ++index) {
+  for (int32_t index = 0; index < static_cast<int32_t>(text.size()); ++index) {
     base_icu::UChar32 code_point;
     if (!base::ReadUnicodeCharacter(text.c_str(), text.size(), &index,
                                     &code_point)) {
diff --git a/remoting/host/me2me_desktop_environment.cc b/remoting/host/me2me_desktop_environment.cc
index 402cece..5394efa 100644
--- a/remoting/host/me2me_desktop_environment.cc
+++ b/remoting/host/me2me_desktop_environment.cc
@@ -58,8 +58,10 @@
   // they disconnect and reconnect. Both OS X and Windows will restore the
   // resolution automatically when the user logs back in on the console, and on
   // Linux the curtain-mode uses a separate session.
-  return base::WrapUnique(new ResizingHostObserver(DesktopResizer::Create(),
-                                                   curtain_ == nullptr));
+  auto resizer = std::make_unique<ResizingHostObserver>(
+      DesktopResizer::Create(), curtain_ == nullptr);
+  resizer->RegisterForDisplayChanges(*GetDisplayInfoMonitor());
+  return resizer;
 }
 
 std::string Me2MeDesktopEnvironment::GetCapabilities() const {
diff --git a/remoting/host/resizing_host_observer.cc b/remoting/host/resizing_host_observer.cc
index d50896b..d2fd8a3 100644
--- a/remoting/host/resizing_host_observer.cc
+++ b/remoting/host/resizing_host_observer.cc
@@ -16,6 +16,7 @@
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "remoting/host/base/screen_resolution.h"
+#include "remoting/host/desktop_display_info_monitor.h"
 #include "remoting/host/desktop_resizer.h"
 
 namespace remoting {
@@ -132,6 +133,12 @@
     RestoreScreenResolution();
 }
 
+void ResizingHostObserver::RegisterForDisplayChanges(
+    DesktopDisplayInfoMonitor& monitor) {
+  monitor.AddCallback(base::BindRepeating(
+      &ResizingHostObserver::OnDisplayInfoChanged, weak_factory_.GetWeakPtr()));
+}
+
 void ResizingHostObserver::SetScreenResolution(
     const ScreenResolution& resolution,
     absl::optional<webrtc::ScreenId> screen_id) {
@@ -210,4 +217,10 @@
   }
 }
 
+void ResizingHostObserver::OnDisplayInfoChanged(
+    const DesktopDisplayInfo& display_info) {
+  // TODO(crbug.com/1326339): Implement this as part of the cross-platform
+  // resizing logic.
+}
+
 }  // namespace remoting
diff --git a/remoting/host/resizing_host_observer.h b/remoting/host/resizing_host_observer.h
index 80515e7a1..7ff7f3d5 100644
--- a/remoting/host/resizing_host_observer.h
+++ b/remoting/host/resizing_host_observer.h
@@ -22,6 +22,8 @@
 
 namespace remoting {
 
+class DesktopDisplayInfo;
+class DesktopDisplayInfoMonitor;
 class DesktopResizer;
 
 // TODO(alexeypa): Rename this class to reflect that it is not
@@ -41,6 +43,8 @@
 
   ~ResizingHostObserver() override;
 
+  void RegisterForDisplayChanges(DesktopDisplayInfoMonitor& monitor);
+
   // ScreenControls interface.
   void SetScreenResolution(const ScreenResolution& resolution,
                            absl::optional<webrtc::ScreenId> screen_id) override;
@@ -53,6 +57,8 @@
  private:
   void RestoreScreenResolution();
 
+  void OnDisplayInfoChanged(const DesktopDisplayInfo& display_info);
+
   std::unique_ptr<DesktopResizer> desktop_resizer_;
   ScreenResolution original_resolution_;
   bool restore_;
diff --git a/sandbox/policy/BUILD.gn b/sandbox/policy/BUILD.gn
index 9a9c8714..6b3f411 100644
--- a/sandbox/policy/BUILD.gn
+++ b/sandbox/policy/BUILD.gn
@@ -155,6 +155,7 @@
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.camera3",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.fonts",
+      "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger",
 
diff --git a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc
index 36169b3..3f5cbb9 100644
--- a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc
+++ b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc
@@ -12,6 +12,7 @@
 #include <fuchsia/buildinfo/cpp/fidl.h>
 #include <fuchsia/camera3/cpp/fidl.h>
 #include <fuchsia/fonts/cpp/fidl.h>
+#include <fuchsia/hwinfo/cpp/fidl.h>
 #include <fuchsia/intl/cpp/fidl.h>
 #include <fuchsia/logger/cpp/fidl.h>
 #include <fuchsia/media/cpp/fidl.h>
@@ -74,8 +75,11 @@
 // clang-format off
 constexpr auto kMinimalServices = base::make_span((const char* const[]){
     // TODO(crbug.com/1286960): Remove this and/or intl below if an alternative
-    // solution does not require access to the service in all processes.
+    // solution does not require access to the service in all processes. For now
+    // these services are made available everywhere because they are required by
+    // base::SysInfo.
     fuchsia::buildinfo::Provider::Name_,
+    fuchsia::hwinfo::Product::Name_,
 
 // DebugData service is needed only for profiling.
 #if BUILDFLAG(CLANG_PROFILING)
diff --git a/services/tracing/public/cpp/perfetto/system_trace_writer.h b/services/tracing/public/cpp/perfetto/system_trace_writer.h
index e3835f3a..579b8b29 100644
--- a/services/tracing/public/cpp/perfetto/system_trace_writer.h
+++ b/services/tracing/public/cpp/perfetto/system_trace_writer.h
@@ -36,19 +36,25 @@
 // Writes system trace data (ftrace or JSON events) to the perfetto SMB. Makes
 // sure to split up the data into small chunks to avoid exhausting the SMB with
 // a large burst of data, as this would cause data loss.
-template <typename StringType>
+template <typename StringType, typename DataSourceType = void>
 class COMPONENT_EXPORT(TRACING_CPP) SystemTraceWriter {
  public:
   enum class TraceType { kFTrace, kJson };
 
   static constexpr size_t kMaxBatchSizeBytes = 1 * 1024 * 1024;  // 1 mB.
 
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  SystemTraceWriter(uint32_t target_buffer, TraceType trace_type)
+      : trace_type_(trace_type),
+        task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
+#else
   SystemTraceWriter(PerfettoProducer* producer,
                     uint32_t target_buffer,
                     TraceType trace_type)
       : trace_writer_(producer->CreateTraceWriter(target_buffer)),
         trace_type_(trace_type),
         task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
+#endif
 
   SystemTraceWriter(const SystemTraceWriter&) = delete;
   SystemTraceWriter& operator=(const SystemTraceWriter&) = delete;
@@ -90,9 +96,8 @@
           internal::GetString(buffered_data_.front()).data() +
           current_data_pos_;
 
-      {
-        perfetto::TraceWriter::TracePacketHandle trace_packet_handle =
-            trace_writer_->NewTracePacket();
+      auto update_packet = [&](perfetto::TraceWriter::TracePacketHandle
+                                   trace_packet_handle) {
         trace_packet_handle->set_timestamp(
             TRACE_TIME_TICKS_NOW().since_origin().InNanoseconds());
         trace_packet_handle->set_timestamp_clock_id(
@@ -113,8 +118,15 @@
             break;
           }
         }
-      }
+      };
 
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+      DataSourceType::Trace([&](typename DataSourceType::TraceContext ctx) {
+        update_packet(ctx.NewTracePacket());
+      });
+#else
+      update_packet(trace_writer_->NewTracePacket());
+#endif
       current_batch_size_ += data_size;
       current_data_pos_ += data_size;
       if (current_data_pos_ >=
@@ -129,15 +141,24 @@
       current_batch_size_ = 0;
       auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
       auto task_runner = task_runner_;
-      trace_writer_->Flush([weak_ptr, task_runner]() {
+      auto flush_callback = [weak_ptr, task_runner]() {
         task_runner->PostTask(
             FROM_HERE,
             base::BindOnce(&SystemTraceWriter::WriteNextBatch, weak_ptr));
+      };
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+      DataSourceType::Trace([&](typename DataSourceType::TraceContext ctx) {
+        ctx.Flush(flush_callback);
       });
+#else
+      trace_writer_->Flush(flush_callback);
+#endif
     }
   }
 
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
   std::unique_ptr<perfetto::TraceWriter> trace_writer_;
+#endif
   TraceType trace_type_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
diff --git a/testing/android/junit/BUILD.gn b/testing/android/junit/BUILD.gn
index e8065ca7..d0f0d967 100644
--- a/testing/android/junit/BUILD.gn
+++ b/testing/android/junit/BUILD.gn
@@ -23,7 +23,6 @@
     "java/src/org/chromium/testing/local/TestDir.java",
   ]
   deps = [
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
diff --git a/testing/android/proguard_for_test.flags b/testing/android/proguard_for_test.flags
index 80eb4f9..8c5707a 100644
--- a/testing/android/proguard_for_test.flags
+++ b/testing/android/proguard_for_test.flags
@@ -24,12 +24,6 @@
   *;
 }
 
-# This matches how we keep @CalledByNative.
--keep @interface org.chromium.base.annotations.CalledByNativeForTesting
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNativeForTesting <methods>;
-}
-
 # Keep all classes that are in test packages. There is no benefit in testing
 # Proguarding of test classes, but this is as close as we can get to selecting
 # all classes from the test apk.
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index db681e0d..cb12c801 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1912,7 +1912,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R102-14695.85.0",
+        "cros_img": "eve-release/R102-14695.107.0",
         "name": "lacros_all_tast_tests EVE_RELEASE_STABLE",
         "resultdb": {
           "enable": true,
@@ -2021,7 +2021,7 @@
       {
         "args": [],
         "cros_board": "hana",
-        "cros_img": "hana-release/R102-14695.85.0",
+        "cros_img": "hana-release/R102-14695.107.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_STABLE",
         "resultdb": {
           "enable": true,
@@ -2126,7 +2126,7 @@
           "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.ozone_unittests.filter"
         ],
         "cros_board": "hana",
-        "cros_img": "hana-release/R102-14695.85.0",
+        "cros_img": "hana-release/R102-14695.107.0",
         "name": "ozone_unittests HANA_RELEASE_STABLE",
         "swarming": {},
         "test": "ozone_unittests",
@@ -2217,7 +2217,7 @@
           "--test-launcher-filter-file=../../testing/buildbot/filters/lacros-arm.viz_unittests.filter"
         ],
         "cros_board": "hana",
-        "cros_img": "hana-release/R102-14695.85.0",
+        "cros_img": "hana-release/R102-14695.107.0",
         "name": "viz_unittests HANA_RELEASE_STABLE",
         "swarming": {},
         "test": "viz_unittests",
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index 4e79869..4139c8a 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1039,48 +1039,48 @@
         "args": [],
         "cros_board": "octopus",
         "cros_img": "octopus-release/R105-14916.0.0",
-        "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM",
+        "name": "lacros_all_tast_tests_informational OCTOPUS_RELEASE_LKGM",
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational || \"name:lacros.VariationSmoke\")",
-        "test": "lacros_fyi_tast_tests",
-        "test_id_prefix": "ninja://chromeos/lacros:lacros_fyi_tast_tests/",
-        "timeout_sec": 10800,
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && informational)",
+        "test": "lacros_all_tast_tests_informational",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests_informational/",
+        "timeout_sec": 25200,
         "variant_id": "OCTOPUS_RELEASE_LKGM"
       },
       {
         "args": [],
         "cros_board": "octopus",
         "cros_img": "octopus-release/R104-14909.7.0",
-        "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_DEV",
+        "name": "lacros_all_tast_tests_informational OCTOPUS_RELEASE_DEV",
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational || \"name:lacros.VariationSmoke\")",
-        "test": "lacros_fyi_tast_tests",
-        "test_id_prefix": "ninja://chromeos/lacros:lacros_fyi_tast_tests/",
-        "timeout_sec": 10800,
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && informational)",
+        "test": "lacros_all_tast_tests_informational",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests_informational/",
+        "timeout_sec": 25200,
         "variant_id": "OCTOPUS_RELEASE_DEV"
       },
       {
         "args": [],
         "cros_board": "octopus",
         "cros_img": "octopus-release/R103-14816.49.0",
-        "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_BETA",
+        "name": "lacros_all_tast_tests_informational OCTOPUS_RELEASE_BETA",
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational || \"name:lacros.VariationSmoke\")",
-        "test": "lacros_fyi_tast_tests",
-        "test_id_prefix": "ninja://chromeos/lacros:lacros_fyi_tast_tests/",
-        "timeout_sec": 10800,
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && informational)",
+        "test": "lacros_all_tast_tests_informational",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests_informational/",
+        "timeout_sec": 25200,
         "variant_id": "OCTOPUS_RELEASE_BETA"
       },
       {
         "args": [],
         "cros_board": "octopus",
         "cros_img": "octopus-release/R102-14695.85.0",
-        "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_STABLE",
+        "name": "lacros_all_tast_tests_informational OCTOPUS_RELEASE_STABLE",
         "swarming": {},
-        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational || \"name:lacros.VariationSmoke\")",
-        "test": "lacros_fyi_tast_tests",
-        "test_id_prefix": "ninja://chromeos/lacros:lacros_fyi_tast_tests/",
-        "timeout_sec": 10800,
+        "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && informational)",
+        "test": "lacros_all_tast_tests_informational",
+        "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests_informational/",
+        "timeout_sec": 25200,
         "variant_id": "OCTOPUS_RELEASE_STABLE"
       },
       {
@@ -1174,7 +1174,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R102-14695.85.0",
+        "cros_img": "strongbad-release/R102-14695.107.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1219,7 +1219,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R102-14695.85.0",
+        "cros_img": "strongbad-release/R102-14695.107.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "test": "ozone_unittests",
@@ -1263,7 +1263,7 @@
       {
         "args": [],
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R102-14695.85.0",
+        "cros_img": "strongbad-release/R102-14695.107.0",
         "name": "viz_unittests STRONGBAD_RELEASE_STABLE",
         "swarming": {},
         "test": "viz_unittests",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index c51929d..764fc168 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3941,9 +3941,9 @@
     },
 
     'lacros_skylab_amd64_fyi': {
-      'lacros_fyi_tast_tests': {
-        'tast_expr': '("group:mainline" && "dep:lacros" && !informational || "name:lacros.VariationSmoke")',
-        'timeout_sec': 10800,
+      'lacros_all_tast_tests_informational': {
+        'tast_expr': '("group:mainline" && "dep:lacros" && informational)',
+        'timeout_sec': 25200,
       },
       'ozone_unittests': {
         'timeout_sec': 3600,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 422ec84..af5c929 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -989,8 +989,8 @@
   'CROS_EVE_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '102.0.5005.75',
-      'cros_img': 'eve-release/R102-14695.85.0',
+      'cros_chrome_version': '102.0.5005.125',
+      'cros_img': 'eve-release/R102-14695.107.0',
     },
     'enabled': True,
     'identifier': 'EVE_RELEASE_STABLE',
@@ -1034,8 +1034,8 @@
     'CROS_HANA_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'hana',
-      'cros_chrome_version': '102.0.5005.75',
-      'cros_img': 'hana-release/R102-14695.85.0',
+      'cros_chrome_version': '102.0.5005.125',
+      'cros_img': 'hana-release/R102-14695.107.0',
     },
     'enabled': True,
     'identifier': 'HANA_RELEASE_STABLE',
@@ -1142,8 +1142,8 @@
   'CROS_STRONGBAD_RELEASE_STABLE': {
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_chrome_version': '102.0.5005.75',
-      'cros_img': 'strongbad-release/R102-14695.85.0',
+      'cros_chrome_version': '102.0.5005.125',
+      'cros_img': 'strongbad-release/R102-14695.107.0',
     },
     'enabled': True,
     'identifier': 'STRONGBAD_RELEASE_STABLE',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f039a8f..27f6a239 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1759,21 +1759,6 @@
             ]
         }
     ],
-    "BlinkCompositorUseDisplayThreadPriority": [
-        {
-            "platforms": [
-                "mac"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "BlinkCompositorUseDisplayThreadPriority"
-                    ]
-                }
-            ]
-        }
-    ],
     "BlinkSchedulerPrioritizeRenderingAfterInput": [
         {
             "platforms": [
@@ -3684,35 +3669,6 @@
             ]
         }
     ],
-    "EnableSuggestedFiles": [
-        {
-            "platforms": [
-                "chromeos"
-            ],
-            "experiments": [
-                {
-                    "name": "Quick_Access",
-                    "params": {
-                        "model_name": "quick_access"
-                    },
-                    "enable_features": [
-                        "EnableSuggestedFiles",
-                        "LauncherItemSuggest"
-                    ]
-                },
-                {
-                    "name": "Future_Access",
-                    "params": {
-                        "model_name": "future_access"
-                    },
-                    "enable_features": [
-                        "EnableSuggestedFiles",
-                        "LauncherItemSuggest"
-                    ]
-                }
-            ]
-        }
-    ],
     "EstablishGpuChannelAsync": [
         {
             "platforms": [
@@ -6892,21 +6848,27 @@
             ],
             "experiments": [
                 {
-                    "name": "EnabledWithContinueSection",
+                    "name": "EnabledWithContinueSection_20220615",
                     "params": {
                         "enable_continue": "true"
                     },
                     "enable_features": [
                         "ProductivityLauncher"
+                    ],
+                    "disable_features": [
+                        "LauncherItemSuggest"
                     ]
                 },
                 {
-                    "name": "EnabledWithoutContinueSection",
+                    "name": "EnabledWithoutContinueSection_20220615",
                     "params": {
                         "enable_continue": "false"
                     },
                     "enable_features": [
                         "ProductivityLauncher"
+                    ],
+                    "disable_features": [
+                        "LauncherItemSuggest"
                     ]
                 }
             ]
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index 1f1d3bdc..96564b4 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -94,6 +94,7 @@
     ??$?0PEAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@Cr@std@@QEAA@AEBV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@PEAX@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@Cr@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$0A@$0A@@Cr@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
+    ??$?0PEBVFormatArgImpl@str_format_internal@absl@@PEAV012@$0A@@?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@Cr@std@@QEAA@$$QEAPEBVFormatArgImpl@str_format_internal@absl@@$$QEAPEAV345@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@$00$00@Cr@std@@QEAA@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0USynchEvent@absl@@@Condition@absl@@QEAA@P6A_NPEAUSynchEvent@1@@Z0@Z
     ??$?0U__value_init_tag@Cr@std@@U012@@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@@23@@Cr@std@@QEAA@$$QEAU__value_init_tag@12@0@Z
@@ -193,6 +194,7 @@
     ??$?RAEAY0N@$$CBDPEAVMutex@absl@@AEA_J@?$AtomicHook@P6AXPEBDPEBX_J@Z@base_internal@absl@@QEBAXAEAY0N@$$CBD$$QEAPEAVMutex@2@AEA_J@Z
     ??$?RAEAY0O@$$CBDPEAVCondVar@absl@@@?$AtomicHook@P6AXPEBDPEBX@Z@base_internal@absl@@QEBAXAEAY0O@$$CBD$$QEAPEAVCondVar@2@@Z
     ??$?RAEA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QEBAXAEA_J@Z
+    ??$?RAEBUTransition@cctz@time_internal@absl@@@__identity@Cr@std@@QEBAAEBUTransition@cctz@time_internal@absl@@AEBU3456@@Z
     ??$?RPEAVSpinLock@base_internal@absl@@AEB_K@?$AtomicHook@P6AXPEBX_J@Z@base_internal@absl@@QEBAX$$QEAPEAVSpinLock@12@AEB_K@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z
@@ -438,6 +440,14 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
     ??$__advance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
     ??$__advance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
+    ??$__allocate_at_least@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEBVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransition@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransitionType@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUViableSubstitution@strings_internal@absl@@@01@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAVFormatArgImpl@str_format_internal@absl@@@01@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@_K@Z
     ??$__construct_at_end@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEBVFormatArgImpl@str_format_internal@absl@@0_K@Z
     ??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
@@ -459,7 +469,8 @@
     ??$__construct_one_at_end@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@Cr@std@@YAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV345@@Z
-    ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@Cr@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
+    ??$__copy@PEBVFormatArgImpl@str_format_internal@absl@@PEBV123@PEAV123@$0A@@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@PEBVFormatArgImpl@str_format_internal@absl@@0PEAV345@@Z
+    ??$__copy_impl@$$CBVFormatArgImpl@str_format_internal@absl@@V123@X@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@PEBVFormatArgImpl@str_format_internal@absl@@0PEAV345@@Z
     ??$__cxx_atomic_compare_exchange_weak@PEAUHashtablezInfo@container_internal@absl@@@Cr@std@@YA_NPEAU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@PEAPEAUHashtablezInfo@container_internal@absl@@PEAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_load@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Cr@std@@YAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZPEBU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@01@W4memory_order@01@@Z
     ??$__cxx_atomic_load@PEAUHashtablezInfo@container_internal@absl@@@Cr@std@@YAPEAUHashtablezInfo@container_internal@absl@@PEBU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@W4memory_order@01@@Z
@@ -471,6 +482,12 @@
     ??$__cxx_atomic_store@PEAVCordzInfo@cord_internal@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@PEAVCordzInfo@cord_internal@absl@@@01@PEAVCordzInfo@cord_internal@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPEAV?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
@@ -479,6 +496,14 @@
     ??$__debug_db_insert_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPEAV?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__distance@PEBUPayload@status_internal@absl@@@Cr@std@@YA_JPEBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -487,9 +512,11 @@
     ??$__distance@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
+    ??$__invoke@AEAU__identity@Cr@std@@AEBUTransition@cctz@time_internal@absl@@@Cr@std@@YAAEBUTransition@cctz@time_internal@absl@@AEAU__identity@01@AEBU2345@@Z
     ??$__launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEBU201@@Z
     ??$__launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEAU201@@Z
-    ??$__lower_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
+    ??$__lower_bound_impl@U_StdIterOps@Cr@std@@PEBUTransition@cctz@time_internal@absl@@PEBU4567@U4567@U__identity@23@UByUnixTime@4567@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@AEAU__identity@01@@Z
     ??$__move@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@Cr@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@Cr@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
     ??$__move@UTransitionType@cctz@time_internal@absl@@U1234@@Cr@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -504,6 +531,7 @@
     ??$__rewrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@0@Z
     ??$__rewrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@0@Z
     ??$__rewrap_iter@PEAVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@0@Z
+    ??$__rewrap_iter@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@0@Z
     ??$__to_address@$$CBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@@Z
     ??$__to_address@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
     ??$__to_address@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@YAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV234@@Z
@@ -520,6 +548,7 @@
     ??$__unwrap_iter@PEBVFormatArgImpl@str_format_internal@absl@@U?$__unwrap_iter_impl@PEBVFormatArgImpl@str_format_internal@absl@@$00@Cr@std@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$__upper_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
+    ??$advance@PEBUTransition@cctz@time_internal@absl@@_J@_StdIterOps@Cr@std@@SAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
     ??$advance@PEBUTransition@cctz@time_internal@absl@@_J_JX@Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
     ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@_K_KX@Cr@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_K@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
@@ -579,6 +608,7 @@
     ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$distance@PEBUPayload@status_internal@absl@@@Cr@std@@YA_JPEBUPayload@status_internal@absl@@0@Z
     ??$distance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0@Z
+    ??$distance@PEBUTransition@cctz@time_internal@absl@@@_StdIterOps@Cr@std@@SA_JPEBUTransition@cctz@time_internal@absl@@0@Z
     ??$distance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$distance@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@0@Z
     ??$distance@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@01@0@Z
@@ -626,6 +656,7 @@
     ??$launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEBU201@@Z
     ??$launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEAU201@@Z
     ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z
+    ??$make_pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@$$QEAPEBVFormatArgImpl@str_format_internal@absl@@$$QEAPEAV345@@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$V@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@AEAV12@@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
     ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -743,7 +774,7 @@
     ??0?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@IEAA@XZ
     ??0?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@Cr@std@@AEAA@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV34567@@Z
     ??0?$__hash_const_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEAA@AEBV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
-    ??0?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@AEAA@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
+    ??0?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@AEAA@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@PEBX@Z
     ??0?$__hash_map_const_iterator@V?$__hash_const_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@V?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@12@@Z
     ??0?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
     ??0?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEAA@XZ
@@ -774,10 +805,10 @@
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
     ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QEAA@XZ
     ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QEAA@XZ
-    ??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
-    ??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AEAA@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@Cr@std@@AEAA@PEBXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@AEAA@PEBXPEAUTransition@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AEAA@PEBXPEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AEAA@PEBXPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??0?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEAA@XZ
     ??0?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@XZ
     ??0?$allocator@PEAUCordRep@cord_internal@absl@@@Cr@std@@QEAA@XZ
@@ -2590,21 +2621,10 @@
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEAAAEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEBAAEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__hash@?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEBA_KXZ
-    ?__invalidate_all_iterators@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
     ?__invalidate_iterators_past@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAVFormatArgImpl@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@PEAPEAVCordzHandle@cord_internal@absl@@@Z
-    ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
     ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@XZ
@@ -2656,19 +2676,11 @@
     ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_K@Z
     ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_K@Z
     ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@@Cr@std@@SAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@AEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAVCordzHandle@cord_internal@absl@@AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEBVCordzHandle@cord_internal@absl@@AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@SAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@23@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUPayload@status_internal@absl@@AEAV?$allocator@UPayload@status_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPEAVFormatArgImpl@str_format_internal@absl@@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@_K@Z
     ?arg@BoundConversion@str_format_internal@absl@@QEBAPEBVFormatArgImpl@23@XZ
     ?as_chars@InlineData@cord_internal@absl@@QEAAPEADXZ
     ?as_chars@InlineData@cord_internal@absl@@QEBAPEBDXZ
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 928cc171..d8838b49 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -78,10 +78,16 @@
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@std@@@absl@@YAHAEBV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@2@@Z
     ??$ToChronoDuration@V?$duration@_JV?$ratio@$00$0DOI@@Cr@std@@@chrono@Cr@std@@@time_internal@absl@@YA?AV?$duration@_JV?$ratio@$00$0DOI@@Cr@std@@@chrono@Cr@std@@VDuration@1@@Z
     ??$ToChronoDuration@V?$duration@_JV?$ratio@$00$0PECEA@@Cr@std@@@chrono@Cr@std@@@time_internal@absl@@YA?AV?$duration@_JV?$ratio@$00$0PECEA@@Cr@std@@@chrono@Cr@std@@VDuration@1@@Z
+    ??$__allocate_at_least@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEBVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransition@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransitionType@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUViableSubstitution@strings_internal@absl@@@01@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAVFormatArgImpl@str_format_internal@absl@@@01@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@_K@Z
     ??$__construct_node_hash@AEBUpiecewise_construct_t@Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@AEAA?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@23@@12@_KAEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
-    ??$__push_back_slow_path@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@optional_internal@absl@@IEAAX$$QEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z
@@ -90,6 +96,7 @@
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXXZ
+    ??$emplace_back@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAVstring_view@5@AEBV65@AEA_K@Z
     ??$find@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAA?AV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@@Z
     ??$find_first_non_full@X@container_internal@absl@@YA?AUFindInfo@01@PEBW4ctrl_t@01@_K1@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@Vstring_view@2@@Z
@@ -103,9 +110,6 @@
     ??0?$RandenPool@I@random_internal@absl@@QEAA@XZ
     ??0?$RandenPool@_K@random_internal@absl@@QEAA@XZ
     ??0?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAA@XZ
-    ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
-    ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
-    ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
     ??0AlphaNum@absl@@QEAA@H@Z
     ??0AlphaNum@absl@@QEAA@UDec@1@@Z
     ??0AlphaNum@absl@@QEAA@UHex@1@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index 534c421..f3317bb 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -94,6 +94,7 @@
     ??$?0PEAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@Cr@std@@QEAA@AEBV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@PEAX@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@Cr@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@X@?$__compressed_pair_elem@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$0A@$0A@@Cr@std@@QEAA@$$QEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
+    ??$?0PEBVFormatArgImpl@str_format_internal@absl@@PEAV012@$0A@@?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@Cr@std@@QEAA@$$QEAPEBVFormatArgImpl@str_format_internal@absl@@$$QEAPEAV345@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@$00$00@Cr@std@@QEAA@$$QEAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0USynchEvent@absl@@@Condition@absl@@QEAA@P6A_NPEAUSynchEvent@1@@Z0@Z
     ??$?0U__value_init_tag@Cr@std@@U012@@?$__compressed_pair@PEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@@23@@Cr@std@@QEAA@$$QEAU__value_init_tag@12@0@Z
@@ -193,6 +194,7 @@
     ??$?RAEAY0N@$$CBDPEAVMutex@absl@@AEA_J@?$AtomicHook@P6AXPEBDPEBX_J@Z@base_internal@absl@@QEBAXAEAY0N@$$CBD$$QEAPEAVMutex@2@AEA_J@Z
     ??$?RAEAY0O@$$CBDPEAVCondVar@absl@@@?$AtomicHook@P6AXPEBDPEBX@Z@base_internal@absl@@QEBAXAEAY0O@$$CBD$$QEAPEAVCondVar@2@@Z
     ??$?RAEA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QEBAXAEA_J@Z
+    ??$?RAEBUTransition@cctz@time_internal@absl@@@__identity@Cr@std@@QEBAAEBUTransition@cctz@time_internal@absl@@AEBU3456@@Z
     ??$?RPEAVSpinLock@base_internal@absl@@AEB_K@?$AtomicHook@P6AXPEBX_J@Z@base_internal@absl@@QEBAX$$QEAPEAVSpinLock@12@AEB_K@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAPEBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAPEBD@Z
     ??$?RW4LogSeverity@absl@@AEBQEBDHAEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PEBDHAEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QEBAX$$QEAW4LogSeverity@2@AEBQEBD$$QEAHAEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z
@@ -438,6 +440,14 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
     ??$__advance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
     ??$__advance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
+    ??$__allocate_at_least@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEAVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAPEBVCordzHandle@cord_internal@absl@@@01@AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransition@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUTransitionType@cctz@time_internal@absl@@@01@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAUViableSubstitution@strings_internal@absl@@@01@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@_K@Z
+    ??$__allocate_at_least@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PEAVFormatArgImpl@str_format_internal@absl@@@01@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@_K@Z
     ??$__construct_at_end@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEBVFormatArgImpl@str_format_internal@absl@@0_K@Z
     ??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
@@ -459,7 +469,8 @@
     ??$__construct_one_at_end@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEBUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAX$$QEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@Cr@std@@YAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PEBVFormatArgImpl@str_format_internal@absl@@1AEAPEAV345@@Z
-    ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@Cr@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEBV234@0PEAV234@@Z
+    ??$__copy@PEBVFormatArgImpl@str_format_internal@absl@@PEBV123@PEAV123@$0A@@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@PEBVFormatArgImpl@str_format_internal@absl@@0PEAV345@@Z
+    ??$__copy_impl@$$CBVFormatArgImpl@str_format_internal@absl@@V123@X@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@PEBVFormatArgImpl@str_format_internal@absl@@0PEAV345@@Z
     ??$__cxx_atomic_compare_exchange_weak@PEAUHashtablezInfo@container_internal@absl@@@Cr@std@@YA_NPEAU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@PEAPEAUHashtablezInfo@container_internal@absl@@PEAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_load@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@Cr@std@@YAP6AXAEBUHashtablezInfo@container_internal@absl@@@ZPEBU?$__cxx_atomic_base_impl@P6AXAEBUHashtablezInfo@container_internal@absl@@@Z@01@W4memory_order@01@@Z
     ??$__cxx_atomic_load@PEAUHashtablezInfo@container_internal@absl@@@Cr@std@@YAPEAUHashtablezInfo@container_internal@absl@@PEBU?$__cxx_atomic_base_impl@PEAUHashtablezInfo@container_internal@absl@@@01@W4memory_order@01@@Z
@@ -471,6 +482,12 @@
     ??$__cxx_atomic_store@PEAVCordzInfo@cord_internal@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@PEAVCordzInfo@cord_internal@absl@@@01@PEAVCordzInfo@cord_internal@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@Cr@std@@YAXPEAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPEAV?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
@@ -479,6 +496,14 @@
     ??$__debug_db_insert_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPEAV?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPEAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__distance@PEBUPayload@status_internal@absl@@@Cr@std@@YA_JPEBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -487,9 +512,11 @@
     ??$__distance@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AEAVstring_view@absl@@AEBV12@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXAEAVstring_view@absl@@AEBV34@AEA_K@Z
     ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@_N@12@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
+    ??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
+    ??$__invoke@AEAU__identity@Cr@std@@AEBUTransition@cctz@time_internal@absl@@@Cr@std@@YAAEBUTransition@cctz@time_internal@absl@@AEAU__identity@01@AEBU2345@@Z
     ??$__launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEBU201@@Z
     ??$__launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEAU201@@Z
-    ??$__lower_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
+    ??$__lower_bound_impl@U_StdIterOps@Cr@std@@PEBUTransition@cctz@time_internal@absl@@PEBU4567@U4567@U__identity@23@UByUnixTime@4567@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@AEAU__identity@01@@Z
     ??$__move@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@@Cr@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@Cr@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@00@Z
     ??$__move@UTransitionType@cctz@time_internal@absl@@U1234@@Cr@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@00@Z
@@ -504,6 +531,7 @@
     ??$__rewrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@YAPEAUTransition@cctz@time_internal@absl@@PEAU2345@0@Z
     ??$__rewrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@YAPEAUTransitionType@cctz@time_internal@absl@@PEAU2345@0@Z
     ??$__rewrap_iter@PEAVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEAVFormatArgImpl@str_format_internal@absl@@PEAV234@0@Z
+    ??$__rewrap_iter@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@0@Z
     ??$__to_address@$$CBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@@Z
     ??$__to_address@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@YAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV23456@@Z
     ??$__to_address@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@YAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV234@@Z
@@ -520,6 +548,7 @@
     ??$__unwrap_iter@PEBVFormatArgImpl@str_format_internal@absl@@U?$__unwrap_iter_impl@PEBVFormatArgImpl@str_format_internal@absl@@$00@Cr@std@@@Cr@std@@YAPEBVFormatArgImpl@str_format_internal@absl@@PEBV234@@Z
     ??$__upper_bound@AEAUByCivilTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByCivilTime@2345@@Z
     ??$__upper_bound@AEAUByUnixTime@Transition@cctz@time_internal@absl@@PEBU2345@U2345@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@AEAUByUnixTime@2345@@Z
+    ??$advance@PEBUTransition@cctz@time_internal@absl@@_J@_StdIterOps@Cr@std@@SAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
     ??$advance@PEBUTransition@cctz@time_internal@absl@@_J_JX@Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_J@Z
     ??$advance@PEBVFormatArgImpl@str_format_internal@absl@@_K_KX@Cr@std@@YAXAEAPEBVFormatArgImpl@str_format_internal@absl@@_K@Z
     ??$assign@PEBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@QEAAXPEBVFormatArgImpl@str_format_internal@absl@@0@Z
@@ -583,6 +612,7 @@
     ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAXAEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PEAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$distance@PEBUPayload@status_internal@absl@@@Cr@std@@YA_JPEBUPayload@status_internal@absl@@0@Z
     ??$distance@PEBUTransition@cctz@time_internal@absl@@@Cr@std@@YA_JPEBUTransition@cctz@time_internal@absl@@0@Z
+    ??$distance@PEBUTransition@cctz@time_internal@absl@@@_StdIterOps@Cr@std@@SA_JPEBUTransition@cctz@time_internal@absl@@0@Z
     ??$distance@PEBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YA_JPEBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$distance@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@01@0@Z
     ??$distance@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA_JV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@01@0@Z
@@ -630,6 +660,7 @@
     ??$launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEBU201@@Z
     ??$launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@01@PEAU201@@Z
     ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@Cr@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z
+    ??$make_pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@Cr@std@@YA?AU?$pair@PEBVFormatArgImpl@str_format_internal@absl@@PEAV123@@01@$$QEAPEBVFormatArgImpl@str_format_internal@absl@@$$QEAPEAV345@@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$V@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@AEAV12@@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
     ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -746,7 +777,7 @@
     ??0?$__deque_base@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@IEAA@XZ
     ??0?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@Cr@std@@AEAA@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV34567@@Z
     ??0?$__hash_const_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEAA@AEBV?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
-    ??0?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@AEAA@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
+    ??0?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@AEAA@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@PEBX@Z
     ??0?$__hash_map_const_iterator@V?$__hash_const_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@V?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@12@@Z
     ??0?$__hash_map_iterator@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@12@@Z
     ??0?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEAA@XZ
@@ -777,10 +808,10 @@
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
     ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QEAA@XZ
     ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QEAA@XZ
-    ??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
-    ??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AEAA@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@Cr@std@@AEAA@PEBXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@Cr@std@@AEAA@PEBXPEAUTransition@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AEAA@PEBXPEAUTransitionType@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AEAA@PEBXPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??0?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEAA@XZ
     ??0?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@QEAA@XZ
     ??0?$allocator@PEAUCordRep@cord_internal@absl@@@Cr@std@@QEAA@XZ
@@ -2590,21 +2621,10 @@
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEAAAEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QEBAAEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__hash@?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@QEBA_KXZ
-    ?__invalidate_all_iterators@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
-    ?__invalidate_all_iterators@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXXZ
     ?__invalidate_iterators_past@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAVFormatArgImpl@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@PEAPEAVCordzHandle@cord_internal@absl@@@Z
-    ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
     ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QEAAAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@XZ
@@ -2657,19 +2677,11 @@
     ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@_K@Z
     ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@_K@Z
     ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@QEAAPEAVFormatArgImpl@str_format_internal@absl@@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@@Cr@std@@SAPEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@AEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEAUCordRep@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAUCordRep@cord_internal@absl@@AEAV?$allocator@PEAUCordRep@cord_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEAVCordzHandle@cord_internal@absl@@AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEBVCordzHandle@cord_internal@absl@@AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@Cr@std@@@Cr@std@@SAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@23@AEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PEAX@Cr@std@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@_K@Z
     ?allocate@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUPayload@status_internal@absl@@AEAV?$allocator@UPayload@status_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUTransition@cctz@time_internal@absl@@AEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@SAPEAUViableSubstitution@strings_internal@absl@@AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@_K@Z
-    ?allocate@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPEAVFormatArgImpl@str_format_internal@absl@@AEAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@_K@Z
     ?arg@BoundConversion@str_format_internal@absl@@QEBAPEBVFormatArgImpl@23@XZ
     ?as_chars@InlineData@cord_internal@absl@@QEAAPEADXZ
     ?as_chars@InlineData@cord_internal@absl@@QEBAPEBDXZ
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index d0387d3..b8172a0b 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -94,6 +94,7 @@
     ??$?0PAUTransitionType@cctz@time_internal@absl@@@?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@Cr@std@@QAE@ABV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@PAX@Z
     ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@Cr@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$QAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@X@?$__compressed_pair_elem@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$0A@$0A@@Cr@std@@QAE@$$QAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
+    ??$?0PBVFormatArgImpl@str_format_internal@absl@@PAV012@$0A@@?$pair@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@Cr@std@@QAE@$$QAPBVFormatArgImpl@str_format_internal@absl@@$$QAPAV345@@Z
     ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@X@?$__compressed_pair_elem@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@$00$00@Cr@std@@QAE@$$QAU?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@12@@Z
     ??$?0USynchEvent@absl@@@Condition@absl@@QAE@P6A_NPAUSynchEvent@1@@Z0@Z
     ??$?0U__value_init_tag@Cr@std@@U012@@?$__compressed_pair@PAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@@23@@Cr@std@@QAE@$$QAU__value_init_tag@12@0@Z
@@ -193,6 +194,7 @@
     ??$?RAAY0N@$$CBDPAVMutex@absl@@AA_J@?$AtomicHook@P6AXPBDPBX_J@Z@base_internal@absl@@QBEXAAY0N@$$CBD$$QAPAVMutex@2@AA_J@Z
     ??$?RAAY0O@$$CBDPAVCondVar@absl@@@?$AtomicHook@P6AXPBDPBX@Z@base_internal@absl@@QBEXAAY0O@$$CBD$$QAPAVCondVar@2@@Z
     ??$?RAA_J@?$AtomicHook@P6AX_J@Z@base_internal@absl@@QBEXAA_J@Z
+    ??$?RABUTransition@cctz@time_internal@absl@@@__identity@Cr@std@@QBEABUTransition@cctz@time_internal@absl@@ABU3456@@Z
     ??$?RPAVSpinLock@base_internal@absl@@AB_K@?$AtomicHook@P6AXPBX_J@Z@base_internal@absl@@QBEX$$QAPAVSpinLock@12@AB_K@Z
     ??$?RW4LogSeverity@absl@@ABQBDHAAPBD@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAHAAPBD@Z
     ??$?RW4LogSeverity@absl@@ABQBDHAAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$AtomicHook@P6AXW4LogSeverity@absl@@PBDHABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z@base_internal@absl@@QBEX$$QAW4LogSeverity@2@ABQBD$$QAHAAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z
@@ -436,6 +438,14 @@
     ??$UnhidePtr@X@base_internal@absl@@YAPAXI@Z
     ??$__advance@PBUTransition@cctz@time_internal@absl@@@Cr@std@@YAXAAPBUTransition@cctz@time_internal@absl@@HUrandom_access_iterator_tag@01@@Z
     ??$__advance@PBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAXAAPBVFormatArgImpl@str_format_internal@absl@@HUrandom_access_iterator_tag@01@@Z
+    ??$__allocate_at_least@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@01@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPAVCordzHandle@cord_internal@absl@@@01@AAV?$allocator@PAVCordzHandle@cord_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPBVCordzHandle@cord_internal@absl@@@01@AAV?$allocator@PBVCordzHandle@cord_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUTransition@cctz@time_internal@absl@@@01@AAV?$allocator@UTransition@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUTransitionType@cctz@time_internal@absl@@@01@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUViableSubstitution@strings_internal@absl@@@01@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAVFormatArgImpl@str_format_internal@absl@@@01@AAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@I@Z
     ??$__construct_at_end@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEXPBVFormatArgImpl@str_format_internal@absl@@0I@Z
     ??$__construct_at_end@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
     ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
@@ -457,7 +467,8 @@
     ??$__construct_one_at_end@ABUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXABUTransition@cctz@time_internal@absl@@@Z
     ??$__construct_one_at_end@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEX$$QAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__construct_range_forward@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@$$CBVFormatArgImpl@str_format_internal@absl@@V456@V456@V456@X@Cr@std@@YAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@PBVFormatArgImpl@str_format_internal@absl@@1AAPAV345@@Z
-    ??$__copy@$$CBVFormatArgImpl@str_format_internal@absl@@V123@@Cr@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PBV234@0PAV234@@Z
+    ??$__copy@PBVFormatArgImpl@str_format_internal@absl@@PBV123@PAV123@$0A@@Cr@std@@YA?AU?$pair@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@01@PBVFormatArgImpl@str_format_internal@absl@@0PAV345@@Z
+    ??$__copy_impl@$$CBVFormatArgImpl@str_format_internal@absl@@V123@X@Cr@std@@YA?AU?$pair@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@01@PBVFormatArgImpl@str_format_internal@absl@@0PAV345@@Z
     ??$__cxx_atomic_compare_exchange_weak@PAUHashtablezInfo@container_internal@absl@@@Cr@std@@YA_NPAU?$__cxx_atomic_base_impl@PAUHashtablezInfo@container_internal@absl@@@01@PAPAUHashtablezInfo@container_internal@absl@@PAU345@W4memory_order@01@3@Z
     ??$__cxx_atomic_load@P6AXABUHashtablezInfo@container_internal@absl@@@Z@Cr@std@@YAP6AXABUHashtablezInfo@container_internal@absl@@@ZPBU?$__cxx_atomic_base_impl@P6AXABUHashtablezInfo@container_internal@absl@@@Z@01@W4memory_order@01@@Z
     ??$__cxx_atomic_load@PAUHashtablezInfo@container_internal@absl@@@Cr@std@@YAPAUHashtablezInfo@container_internal@absl@@PBU?$__cxx_atomic_base_impl@PAUHashtablezInfo@container_internal@absl@@@01@W4memory_order@01@@Z
@@ -469,6 +480,12 @@
     ??$__cxx_atomic_store@PAVCordzInfo@cord_internal@absl@@@Cr@std@@YAXPAU?$__cxx_atomic_base_impl@PAVCordzInfo@cord_internal@absl@@@01@PAVCordzInfo@cord_internal@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4OnDeadlockCycle@absl@@@Cr@std@@YAXPAU?$__cxx_atomic_base_impl@W4OnDeadlockCycle@absl@@@01@W4OnDeadlockCycle@absl@@W4memory_order@01@@Z
     ??$__cxx_atomic_store@W4State@PerThreadSynch@base_internal@absl@@@Cr@std@@YAXPAU?$__cxx_atomic_base_impl@W4State@PerThreadSynch@base_internal@absl@@@01@W4State@PerThreadSynch@base_internal@absl@@W4memory_order@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_erase_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPAV?$unordered_map@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
@@ -477,6 +494,14 @@
     ??$__debug_db_insert_c@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
     ??$__debug_db_insert_c@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@@Cr@std@@YAXPAV?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@01@@Z
+    ??$__debug_db_invalidate_all@V?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@@Cr@std@@YAXPAV?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@01@@Z
     ??$__distance@PBUPayload@status_internal@absl@@@Cr@std@@YAHPBUPayload@status_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PBUTransition@cctz@time_internal@absl@@@Cr@std@@YAHPBUTransition@cctz@time_internal@absl@@0Urandom_access_iterator_tag@01@@Z
     ??$__distance@PBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAHPBVFormatArgImpl@str_format_internal@absl@@0Urandom_access_iterator_tag@01@@Z
@@ -485,9 +510,11 @@
     ??$__distance@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAHV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@01@0Urandom_access_iterator_tag@01@@Z
     ??$__emplace_back_slow_path@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AAEXAAVstring_view@absl@@ABV34@AAI@Z
     ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
+    ??$__invoke@AAUByUnixTime@Transition@cctz@time_internal@absl@@ABU2345@ABU2345@@Cr@std@@YA_NAAUByUnixTime@Transition@cctz@time_internal@absl@@ABU3456@1@Z
+    ??$__invoke@AAU__identity@Cr@std@@ABUTransition@cctz@time_internal@absl@@@Cr@std@@YAABUTransition@cctz@time_internal@absl@@AAU__identity@01@ABU2345@@Z
     ??$__launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@01@PBU201@@Z
     ??$__launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@01@PAU201@@Z
-    ??$__lower_bound@AAUByUnixTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByUnixTime@2345@@Z
+    ??$__lower_bound_impl@U_StdIterOps@Cr@std@@PBUTransition@cctz@time_internal@absl@@PBU4567@U4567@U__identity@23@UByUnixTime@4567@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByUnixTime@2345@AAU__identity@01@@Z
     ??$__move@PAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@@Cr@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@00@Z
     ??$__move@UTransition@cctz@time_internal@absl@@U1234@@Cr@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@00@Z
     ??$__move@UTransitionType@cctz@time_internal@absl@@U1234@@Cr@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@00@Z
@@ -502,6 +529,7 @@
     ??$__rewrap_iter@PAUTransition@cctz@time_internal@absl@@@Cr@std@@YAPAUTransition@cctz@time_internal@absl@@PAU2345@0@Z
     ??$__rewrap_iter@PAUTransitionType@cctz@time_internal@absl@@@Cr@std@@YAPAUTransitionType@cctz@time_internal@absl@@PAU2345@0@Z
     ??$__rewrap_iter@PAVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPAVFormatArgImpl@str_format_internal@absl@@PAV234@0@Z
+    ??$__rewrap_iter@PBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPBVFormatArgImpl@str_format_internal@absl@@PBV234@0@Z
     ??$__to_address@$$CBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAPBVFormatArgImpl@str_format_internal@absl@@PBV234@@Z
     ??$__to_address@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@YAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV23456@@Z
     ??$__to_address@PAVCordzHandle@cord_internal@absl@@@Cr@std@@YAPAPAVCordzHandle@cord_internal@absl@@PAPAV234@@Z
@@ -518,6 +546,7 @@
     ??$__unwrap_iter@PBVFormatArgImpl@str_format_internal@absl@@U?$__unwrap_iter_impl@PBVFormatArgImpl@str_format_internal@absl@@$00@Cr@std@@@Cr@std@@YAPBVFormatArgImpl@str_format_internal@absl@@PBV234@@Z
     ??$__upper_bound@AAUByCivilTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByCivilTime@2345@@Z
     ??$__upper_bound@AAUByUnixTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByUnixTime@2345@@Z
+    ??$advance@PBUTransition@cctz@time_internal@absl@@H@_StdIterOps@Cr@std@@SAXAAPBUTransition@cctz@time_internal@absl@@H@Z
     ??$advance@PBUTransition@cctz@time_internal@absl@@HHX@Cr@std@@YAXAAPBUTransition@cctz@time_internal@absl@@H@Z
     ??$advance@PBVFormatArgImpl@str_format_internal@absl@@IIX@Cr@std@@YAXAAPBVFormatArgImpl@str_format_internal@absl@@I@Z
     ??$assign@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@QAEXPBVFormatArgImpl@str_format_internal@absl@@0@Z
@@ -579,6 +608,7 @@
     ??$destroy@VFormatArgImpl@str_format_internal@absl@@X@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAXAAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@12@PAVFormatArgImpl@str_format_internal@absl@@@Z
     ??$distance@PBUPayload@status_internal@absl@@@Cr@std@@YAHPBUPayload@status_internal@absl@@0@Z
     ??$distance@PBUTransition@cctz@time_internal@absl@@@Cr@std@@YAHPBUTransition@cctz@time_internal@absl@@0@Z
+    ??$distance@PBUTransition@cctz@time_internal@absl@@@_StdIterOps@Cr@std@@SAHPBUTransition@cctz@time_internal@absl@@0@Z
     ??$distance@PBVFormatArgImpl@str_format_internal@absl@@@Cr@std@@YAHPBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$distance@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAHV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@01@0@Z
     ??$distance@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAHV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@01@0@Z
@@ -625,6 +655,7 @@
     ??$launder@$$CBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@01@PBU201@@Z
     ??$launder@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YAPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@01@PAU201@@Z
     ??$lower_bound@PBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@UByUnixTime@2345@@Z
+    ??$make_pair@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@Cr@std@@YA?AU?$pair@PBVFormatArgImpl@str_format_internal@absl@@PAV123@@01@$$QAPBVFormatArgImpl@str_format_internal@absl@@$$QAPAV345@@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@$$V@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@AAV12@@Cr@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Cr@std@@@01@AAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@absl@@@Z
     ??$max_size@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAIABV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -741,7 +772,7 @@
     ??0?$__deque_base@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@IAE@XZ
     ??0?$__deque_iterator@PBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@AAPBV12345@PAPAPBV12345@H$0A@@Cr@std@@AAE@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPBV34567@@Z
     ??0?$__hash_const_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@QAE@ABV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@12@@Z
-    ??0?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@AAE@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@12@@Z
+    ??0?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@AAE@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@12@PBX@Z
     ??0?$__hash_map_const_iterator@V?$__hash_const_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@QAE@V?$__hash_map_iterator@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@12@@Z
     ??0?$__hash_map_iterator@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@QAE@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@12@@Z
     ??0?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@QAE@XZ
@@ -772,10 +803,10 @@
     ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
     ??0?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QAE@XZ
     ??0?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@Cr@std@@QAE@XZ
-    ??0?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@Cr@std@@AAE@PAPAVCordzHandle@cord_internal@absl@@@Z
-    ??0?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@Cr@std@@AAE@PAUTransition@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AAE@PAUTransitionType@cctz@time_internal@absl@@@Z
-    ??0?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AAE@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+    ??0?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@Cr@std@@AAE@PBXPAPAVCordzHandle@cord_internal@absl@@@Z
+    ??0?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@Cr@std@@AAE@PBXPAUTransition@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@Cr@std@@AAE@PBXPAUTransitionType@cctz@time_internal@absl@@@Z
+    ??0?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@AAE@PBXPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??0?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QAE@XZ
     ??0?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@QAE@XZ
     ??0?$allocator@PAUCordRep@cord_internal@absl@@@Cr@std@@QAE@XZ
@@ -2585,21 +2616,10 @@
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QAEAAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__get_value@?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@QBEABU?$pair@$$CBV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
     ?__hash@?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@QBEIXZ
-    ?__invalidate_all_iterators@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
-    ?__invalidate_all_iterators@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEXXZ
     ?__invalidate_iterators_past@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAUTransitionType@cctz@time_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAUViableSubstitution@strings_internal@absl@@@Z
     ?__invalidate_iterators_past@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAVFormatArgImpl@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@AAE?AV?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@23@PAPAVCordzHandle@cord_internal@absl@@@Z
-    ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@ABE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@PAUTransition@cctz@time_internal@absl@@@Z
-    ?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@PAUTransitionType@cctz@time_internal@absl@@@Z
     ?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@00@Z
     ?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXPAUTransitionType@cctz@time_internal@absl@@00@Z
     ?__node_alloc@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QAEAAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@23@XZ
@@ -2652,19 +2672,11 @@
     ?allocate@?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@I@Z
     ?allocate@?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@I@Z
     ?allocate@?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@QAEPAVFormatArgImpl@str_format_internal@absl@@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@@Cr@std@@SAPAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@23@AAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@PAUCordRep@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPAPAUCordRep@cord_internal@absl@@AAV?$allocator@PAUCordRep@cord_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPAPAVCordzHandle@cord_internal@absl@@AAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@SAPAPBVCordzHandle@cord_internal@absl@@AAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@Cr@std@@SAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@23@AAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@I@Z
     ?allocate@?$allocator_traits@V?$allocator@UPayload@status_internal@absl@@@Cr@std@@@Cr@std@@SAPAUPayload@status_internal@absl@@AAV?$allocator@UPayload@status_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPAUTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@SAPAUTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@SAPAUViableSubstitution@strings_internal@absl@@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@I@Z
-    ?allocate@?$allocator_traits@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@SAPAVFormatArgImpl@str_format_internal@absl@@AAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@23@I@Z
     ?arg@BoundConversion@str_format_internal@absl@@QBEPBVFormatArgImpl@23@XZ
     ?as_chars@InlineData@cord_internal@absl@@QAEPADXZ
     ?as_chars@InlineData@cord_internal@absl@@QBEPBDXZ
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 66b8ae84..647ba30 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -76,11 +76,16 @@
     ??$SetEdge@$0A@@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@std@@@absl@@YA?AV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@Vstring_view@0@ABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@3@@Z
     ??$StrReplaceAll@V?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@std@@@absl@@YAHABV?$initializer_list@U?$pair@Vstring_view@absl@@V12@@Cr@std@@@std@@PAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@2@@Z
+    ??$__allocate_at_least@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@01@AAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@PAVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPAVCordzHandle@cord_internal@absl@@@01@AAV?$allocator@PAVCordzHandle@cord_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@PBVCordzHandle@cord_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAPBVCordzHandle@cord_internal@absl@@@01@AAV?$allocator@PBVCordzHandle@cord_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUTransition@cctz@time_internal@absl@@@01@AAV?$allocator@UTransition@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUTransitionType@cctz@time_internal@absl@@@01@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAUViableSubstitution@strings_internal@absl@@@01@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@01@I@Z
+    ??$__allocate_at_least@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@YA?AU?$__allocation_result@PAVFormatArgImpl@str_format_internal@absl@@@01@AAV?$allocator@VFormatArgImpl@str_format_internal@absl@@@01@I@Z
     ??$__construct_node_hash@ABUpiecewise_construct_t@Cr@std@@V?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@AAE?AV?$unique_ptr@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@@23@@12@IABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
-    ??$__emplace_back_slow_path@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@AAEXAAVstring_view@absl@@ABV34@AAI@Z
     ??$__emplace_unique_key_args@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@ABUpiecewise_construct_t@23@V?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QAE?AU?$pair@V?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@Cr@std@@_N@12@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
-    ??$__push_back_slow_path@ABUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@AAEXABUTransition@cctz@time_internal@absl@@@Z
-    ??$__push_back_slow_path@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@AAEX$$QAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
     ??$__upper_bound@AAUByCivilTime@Transition@cctz@time_internal@absl@@PBU2345@U2345@@Cr@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@AAUByCivilTime@2345@@Z
     ??$assign@PBVFormatArgImpl@str_format_internal@absl@@@?$vector@VFormatArgImpl@str_format_internal@absl@@V?$allocator@VFormatArgImpl@str_format_internal@absl@@@Cr@std@@@Cr@std@@QAEXPBVFormatArgImpl@str_format_internal@absl@@0@Z
     ??$assign@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$optional_data_base@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@optional_internal@absl@@IAEX$$QAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@Z
@@ -89,6 +94,7 @@
     ??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@12@@Z
     ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAEXXZ
     ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAEXXZ
+    ??$emplace_back@AAVstring_view@absl@@ABV12@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QAEAAUViableSubstitution@strings_internal@absl@@AAVstring_view@5@ABV65@AAI@Z
     ??$find@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@@23@$00@23@V?$allocator@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@@23@@Cr@std@@QAE?AV?$__hash_iterator@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@Cr@std@@PAX@Cr@std@@@12@ABV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@12@@Z
     ??$find_first_non_full@X@container_internal@absl@@YA?AUFindInfo@01@PBW4ctrl_t@01@II@Z
     ??0?$BigUnsigned@$03@strings_internal@absl@@QAE@Vstring_view@2@@Z
@@ -102,10 +108,6 @@
     ??0?$RandenPool@I@random_internal@absl@@QAE@XZ
     ??0?$RandenPool@_K@random_internal@absl@@QAE@XZ
     ??0?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAE@XZ
-    ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@AAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@Cr@std@@@Cr@std@@QAE@IIAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
-    ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@AAV?$allocator@UTransition@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
-    ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@AAV?$allocator@UTransitionType@cctz@time_internal@absl@@@Cr@std@@@Cr@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
-    ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@AAV?$allocator@UViableSubstitution@strings_internal@absl@@@Cr@std@@@Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
     ??0AlphaNum@absl@@QAE@H@Z
     ??0AlphaNum@absl@@QAE@I@Z
     ??0AlphaNum@absl@@QAE@UDec@1@@Z
diff --git a/third_party/blink/public/common/tokens/token_mojom_traits_helper.h b/third_party/blink/public/common/tokens/token_mojom_traits_helper.h
index 0f5ee10a3..f4912cae 100644
--- a/third_party/blink/public/common/tokens/token_mojom_traits_helper.h
+++ b/third_party/blink/public/common/tokens/token_mojom_traits_helper.h
@@ -20,6 +20,9 @@
     base::UnguessableToken token;
     if (!input.ReadValue(&token))
       return false;
+    // UnguessableToken's StructTraits ensures that `token` will never be
+    // empty.
+    CHECK(!token.is_empty());
     *output = TokenType(token);
     return true;
   }
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 7740c883..c0016b70 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8006,12 +8006,12 @@
     parameters
       # Id of the frame containing input node.
       experimental FrameId frameId
-      # Input node id.
-      experimental DOM.BackendNodeId backendNodeId
       # Input mode.
       enum mode
         selectSingle
         selectMultiple
+      # Input node id. Only present for file choosers opened via an <input type="file"> element.
+      experimental optional DOM.BackendNodeId backendNodeId
 
   # Fired when frame has been attached to its parent.
   event frameAttached
diff --git a/third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom b/third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom
index c3028c50..e6b8eaf1 100644
--- a/third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom
+++ b/third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom
@@ -27,7 +27,13 @@
   Navigate(url.mojom.Url url, mojo_base.mojom.TimeTicks navigation_start_time);
 };
 
-enum ReportingDestination { kBuyer, kSeller, kComponentSeller };
+enum ReportingDestination {
+  kBuyer,
+  kSeller,
+  kComponentSeller,
+  kSharedStorageSelectUrl
+};
+
 struct FencedFrameReporting {
   // If this is an "opaque-ads" mode fenced frame, there might be an associated
   // reporting metadata. This is a map from destination type to reporting
diff --git a/third_party/blink/public/mojom/shared_storage/shared_storage.mojom b/third_party/blink/public/mojom/shared_storage/shared_storage.mojom
index b3308f8..57fcf66 100644
--- a/third_party/blink/public/mojom/shared_storage/shared_storage.mojom
+++ b/third_party/blink/public/mojom/shared_storage/shared_storage.mojom
@@ -21,6 +21,14 @@
   mojo_base.mojom.String16 data;
 };
 
+// Bundles a candidate URL for `RunURLSelectionOperationOnWorklet()` with any
+// `reporting metadata` (map of each report event type to report URL) for
+// event-level reporting.
+struct SharedStorageUrlWithMetadata {
+  url.mojom.Url url;
+  map<string, url.mojom.Url> reporting_metadata;
+};
+
 // SharedStorage is an origin-keyed storage mechanism where the output is
 // carefully guarded to mitigate the risk of cross-site correlation.
 // See https://github.com/pythagoraskitty/shared-storage/blob/main/README.md
@@ -61,7 +69,8 @@
   // data will be only consumed in an environment (i.e. the worklet) in control
   // by the same origin.
   RunURLSelectionOperationOnWorklet(string name,
-                                    array<url.mojom.Url> urls,
+                                    array<SharedStorageUrlWithMetadata>
+                                      urls_with_metadata,
                                     array<uint8> serialized_data)
     => (bool success, string error_message, url.mojom.Url opaque_url);
 
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 64b31e70..47aeb60 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -903,6 +903,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_share_data.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_run_operation_method_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_run_operation_method_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_set_method_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_set_method_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index 2bfd817..efb65ac 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -705,6 +705,7 @@
           "//third_party/blink/renderer/modules/shapedetection/landmark.idl",
           "//third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl",
           "//third_party/blink/renderer/modules/shared_storage/shared_storage.idl",
+          "//third_party/blink/renderer/modules/shared_storage/shared_storage_url_with_metadata.idl",
           "//third_party/blink/renderer/modules/shared_storage/shared_storage_worklet.idl",
           "//third_party/blink/renderer/modules/shared_storage/shared_storage_set_method_options.idl",
           "//third_party/blink/renderer/modules/shared_storage/shared_storage_run_operation_method_options.idl",
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
index 46e9625..cc225c4 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
@@ -594,8 +594,15 @@
   // MediaSourceHandleImpl. Add the internal state of |handle| to it and
   // serialize it using the index of that state in the vector.
   auto& attachments = attachment->Attachments();
+
+  scoped_refptr<MediaSourceAttachment> media_source_attachment =
+      handle->TakeAttachment();
+  // The two handle checks, above, (!is_serialized() and !is_used()) should
+  // prevent us from ever having a missing |media_source_attachment| here.
+  DCHECK(media_source_attachment);
+
   attachments.push_back(MediaSourceHandleAttachment::HandleInternals{
-      .attachment = handle->GetAttachment(),
+      .attachment = std::move(media_source_attachment),
       .internal_blob_url = handle->GetInternalBlobURL()});
   handle->mark_serialized();
   const uint32_t index = static_cast<uint32_t>(attachments.size() - 1);
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc
index c7b54af1..6c6cca4f 100644
--- a/third_party/blink/renderer/core/css/css_selector.cc
+++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -148,6 +148,11 @@
         case kPseudoSlotted:
           DCHECK(SelectorList()->HasOneSelector());
           return kClassLikeSpecificity + SelectorList()->First()->Specificity();
+        case kPseudoPageTransitionContainer:
+        case kPseudoPageTransitionImageWrapper:
+        case kPseudoPageTransitionOutgoingImage:
+        case kPseudoPageTransitionIncomingImage:
+          return Argument().IsNull() ? 0 : kClassLikeSpecificity;
         default:
           break;
       }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 98e4b66..84eca5b 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2314,9 +2314,18 @@
 
 Fence* LocalDOMWindow::fence() {
   // Return nullptr if we aren't in a fenced subtree.
-  if (!GetFrame() || !GetFrame()->IsInFencedFrameTree()) {
+  if (!GetFrame()) {
     return nullptr;
   }
+  if (!GetFrame()->IsInFencedFrameTree()) {
+    // We temporarily allow window.fence in iframes with fenced frame reporting
+    // metadata (navigated by urn:uuids).
+    // If we are in an iframe that doesn't qualify, return nullptr.
+    if (!blink::features::IsAllowURNsInIframeEnabled() ||
+        !GetFrame()->GetDocument()->Loader()->FencedFrameReporting()) {
+      return nullptr;
+    }
+  }
 
   if (!fence_) {
     fence_ = MakeGarbageCollected<Fence>(*this);
diff --git a/third_party/blink/renderer/core/html/fenced_frame/fence.cc b/third_party/blink/renderer/core/html/fenced_frame/fence.cc
index 7a6b1a6..856abe9 100644
--- a/third_party/blink/renderer/core/html/fenced_frame/fence.cc
+++ b/third_party/blink/renderer/core/html/fenced_frame/fence.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/html/fenced_frame/fence.h"
 
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/frame/frame_policy.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
 #include "third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom-blink.h"
@@ -32,6 +33,8 @@
       return mojom::blink::ReportingDestination::kSeller;
     case V8FenceReportingDestination::Enum::kComponentSeller:
       return mojom::blink::ReportingDestination::kComponentSeller;
+    case V8FenceReportingDestination::Enum::kSharedStorageSelectUrl:
+      return mojom::blink::ReportingDestination::kSharedStorageSelectUrl;
   }
 }
 
@@ -56,17 +59,34 @@
 
   LocalFrame* frame = DomWindow()->GetFrame();
   DCHECK(frame);
-  DCHECK(frame->IsInFencedFrameTree());
 
-  if (frame->GetFencedFrameMode() !=
-      mojom::blink::FencedFrameMode::kOpaqueAds) {
-    AddConsoleMessage(
-        "fence.reportEvent is only available in the 'opaque-ads' mode.");
-    return;
+  LocalFrame* fenced_frame = nullptr;
+  if (blink::features::IsAllowURNsInIframeEnabled() &&
+      !frame->IsInFencedFrameTree()) {
+    // The only way to get a Fence outside a fenced frame is from
+    // LocalDOMWindow::fence(), when both:
+    // - blink::features::IsAllowURNsInIframeEnabled() is true
+    // - the Document itself was loaded from a urn:uuid
+    // In that case, pretend that the frame is a fenced frame root for this
+    // temporary experiment.
+    // TODO(crbug.com/1123606): Disable window.fence.reportEvent in iframes.
+    // In order to disable, run the else branch unconditionally.
+    // Also remove the features.h include above.
+    fenced_frame = frame;
+  } else {
+    DCHECK(frame->IsInFencedFrameTree());
+
+    if (frame->GetFencedFrameMode() !=
+        mojom::blink::FencedFrameMode::kOpaqueAds) {
+      AddConsoleMessage(
+          "fence.reportEvent is only available in the 'opaque-ads' mode.");
+      return;
+    }
+
+    fenced_frame = DynamicTo<LocalFrame>(
+        DomWindow()->GetFrame()->Top(FrameTreeBoundary::kFenced));
   }
 
-  LocalFrame* fenced_frame = DynamicTo<LocalFrame>(
-      DomWindow()->GetFrame()->Top(FrameTreeBoundary::kFenced));
   DCHECK(fenced_frame);
   DCHECK(fenced_frame->GetDocument());
 
diff --git a/third_party/blink/renderer/core/html/fenced_frame/fence_event.idl b/third_party/blink/renderer/core/html/fenced_frame/fence_event.idl
index 4ded7eff..44fc3721 100644
--- a/third_party/blink/renderer/core/html/fenced_frame/fence_event.idl
+++ b/third_party/blink/renderer/core/html/fenced_frame/fence_event.idl
@@ -2,7 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-enum FenceReportingDestination {"buyer", "seller", "component-seller"};
+enum FenceReportingDestination {
+  "buyer",
+  "seller",
+  "component-seller",
+  "shared-storage-select-url"
+};
 
 dictionary FenceEvent {
   required DOMString eventType;
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type.cc b/third_party/blink/renderer/core/html/forms/file_input_type.cc
index 49aa669..2eadda4 100644
--- a/third_party/blink/renderer/core/html/forms/file_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/file_input_type.cc
@@ -172,7 +172,8 @@
   }
 
   bool intercepted = false;
-  probe::FileChooserOpened(document.GetFrame(), &input, &intercepted);
+  probe::FileChooserOpened(document.GetFrame(), &input, input.Multiple(),
+                           &intercepted);
   if (intercepted) {
     event.SetDefaultHandled();
     return;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index fa373a5..a033cf9 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -1383,8 +1383,13 @@
   bool attempt_load = true;
 
   if (src_object_media_source_handle_) {
-    media_source_attachment_ = src_object_media_source_handle_->GetAttachment();
-    DCHECK(media_source_attachment_);
+    media_source_attachment_ =
+        src_object_media_source_handle_->TakeAttachment();
+
+    // If the attachment is nullptr, then fail the load.
+    if (!media_source_attachment_) {
+      attempt_load = false;
+    }
   } else {
     media_source_attachment_ =
         MediaSourceAttachment::LookupMediaSource(url.GetString());
diff --git a/third_party/blink/renderer/core/html/media/media_source_handle.h b/third_party/blink/renderer/core/html/media/media_source_handle.h
index acccad95..141ce60 100644
--- a/third_party/blink/renderer/core/html/media/media_source_handle.h
+++ b/third_party/blink/renderer/core/html/media/media_source_handle.h
@@ -18,7 +18,9 @@
   MediaSourceHandle& operator=(const MediaSourceHandle&) = delete;
   virtual ~MediaSourceHandle() = default;
 
-  virtual scoped_refptr<MediaSourceAttachment> GetAttachment() = 0;
+  // Removes our reference on the attachment, giving it to the caller.
+  virtual scoped_refptr<MediaSourceAttachment> TakeAttachment() = 0;
+
   virtual String GetInternalBlobURL() = 0;
 
   void mark_used() { used_ = true; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index f0788d9..60eb78a0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -1761,15 +1761,16 @@
 
 void InspectorPageAgent::FileChooserOpened(LocalFrame* frame,
                                            HTMLInputElement* element,
+                                           bool multiple,
                                            bool* intercepted) {
   *intercepted |= intercept_file_chooser_.Get();
   if (!intercept_file_chooser_.Get())
     return;
-  bool multiple = element->Multiple();
   GetFrontend()->fileChooserOpened(
-      IdentifiersFactory::FrameId(frame), DOMNodeIds::IdForNode(element),
+      IdentifiersFactory::FrameId(frame),
       multiple ? protocol::Page::FileChooserOpened::ModeEnum::SelectMultiple
-               : protocol::Page::FileChooserOpened::ModeEnum::SelectSingle);
+               : protocol::Page::FileChooserOpened::ModeEnum::SelectSingle,
+      element ? Maybe<int>(DOMNodeIds::IdForNode(element)) : Maybe<int>());
 }
 
 Response InspectorPageAgent::produceCompilationCache(
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
index 8c1d8c8d..1cc8485 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -239,6 +239,7 @@
                                   v8::Local<v8::Script> script);
   void FileChooserOpened(LocalFrame* frame,
                          HTMLInputElement* element,
+                         bool multiple,
                          bool* intercepted);
 
   // Inspector Controller API
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl
index 28fc486..ad23e3a8 100644
--- a/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -179,7 +179,7 @@
   void ApplyCompilationModeOverride(ExecutionContext*, const ClassicScript&, v8::ScriptCompiler::CachedData** cached_data, v8::ScriptCompiler::CompileOptions*);
   void NodeCreated([Keep] Node* node);
   void PortalRemoteFrameCreated(Document*, HTMLPortalElement* portal_element);
-  void FileChooserOpened([Keep] LocalFrame* frame, HTMLInputElement* element, bool* intercepted);
+  void FileChooserOpened([Keep] LocalFrame* frame, HTMLInputElement* element, bool multiple, bool* intercepted);
   void PlayerErrorsRaised(ExecutionContext* context, String player_id, const Vector<InspectorPlayerError>& errors);
   void PlayerEventsAdded(ExecutionContext* context, String player_id, const Vector<InspectorPlayerEvent>& events);
   void PlayerMessagesLogged(ExecutionContext* context, String player_id, const Vector<InspectorPlayerMessage>& messages);
diff --git a/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc b/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
index 52fa55e..21a9bf3f 100644
--- a/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
+++ b/third_party/blink/renderer/modules/file_system_access/global_file_system_access.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/core/fileapi/file_error.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/modules/file_system_access/file_system_access_error.h"
 #include "third_party/blink/renderer/modules/file_system_access/file_system_directory_handle.h"
@@ -227,7 +228,22 @@
     LocalDOMWindow& window,
     mojom::blink::FilePickerOptionsPtr options,
     mojom::blink::CommonFilePickerOptionsPtr common_options,
+    ExceptionState& exception_state,
     bool return_as_sequence) {
+  bool multiple =
+      options->which() ==
+          mojom::blink::FilePickerOptions::Tag::kOpenFilePickerOptions &&
+      options->get_open_file_picker_options()->can_select_multiple_files;
+  bool intercepted = false;
+  probe::FileChooserOpened(window.GetFrame(), /*element=*/nullptr, multiple,
+                           &intercepted);
+  if (intercepted) {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kAbortError,
+        "Intercepted by Page.setInterceptFileChooserDialog().");
+    return ScriptPromise();
+  }
+
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise resolver_result = resolver->Promise();
 
@@ -350,6 +366,7 @@
       mojom::blink::CommonFilePickerOptions::New(
           std::move(starting_directory_id),
           std::move(well_known_starting_directory), std::move(token)),
+      exception_state,
       /*return_as_sequence=*/true);
 }
 
@@ -414,6 +431,7 @@
       mojom::blink::CommonFilePickerOptions::New(
           std::move(starting_directory_id),
           std::move(well_known_starting_directory), std::move(token)),
+      exception_state,
       /*return_as_sequence=*/false);
 }
 
@@ -464,6 +482,7 @@
       mojom::blink::CommonFilePickerOptions::New(
           std::move(starting_directory_id),
           std::move(well_known_starting_directory), std::move(token)),
+      exception_state,
       /*return_as_sequence=*/false);
 }
 
diff --git a/third_party/blink/renderer/modules/mediasource/cross_thread_media_source_attachment.cc b/third_party/blink/renderer/modules/mediasource/cross_thread_media_source_attachment.cc
index 82683ab7..1a09903 100644
--- a/third_party/blink/renderer/modules/mediasource/cross_thread_media_source_attachment.cc
+++ b/third_party/blink/renderer/modules/mediasource/cross_thread_media_source_attachment.cc
@@ -494,6 +494,11 @@
     MutexLocker lock(attachment_state_lock_);
     DCHECK(registered_media_source_);
 
+    // MSE-in-Worker using MediaSourceHandle for attachment does NOT use object
+    // URLs, so we must not be called if MediaSourceHandle feature is enabled.
+    DCHECK(!RuntimeEnabledFeatures::MediaSourceInWorkersUsingHandleEnabled(
+        registered_media_source_->GetExecutionContext()));
+
     // The only expected caller is a MediaSourceRegistryImpl on the main thread
     // (or possibly on the worker thread, if MediaSourceInWorkers is enabled).
     DCHECK(IsMainThread() ||
@@ -528,10 +533,21 @@
     // Prevent sequential re-use of this attachment for multiple successful
     // attachments. See declaration of |have_ever_attached_|.
     if (have_ever_attached_) {
-      DVLOG(1) << __func__ << " this=" << this << ", element=" << element
-               << ": failed: reuse of MediaSource object URL by disabling "
-                  "RevokeMediaSourceObjectURLOnAttach is not supported for "
-                  "MSE-in-Workers";
+      if (RuntimeEnabledFeatures::MediaSourceInWorkersUsingHandleEnabled(
+              element->GetExecutionContext())) {
+        // With current restrictions on ability to only ever obtain at most one
+        // MediaSourceHandle per MediaSource and only allow loading to succeed
+        // at most once per each MediaSourceHandle, fail if there is attempt to
+        // reuse either in a load.
+        DVLOG(1) << __func__ << " this=" << this << ", element=" << element
+                 << ": failed: reuse of MediaSource for more than one load "
+                    "is not supported for MSE-in-Workers";
+      } else {
+        DVLOG(1) << __func__ << " this=" << this << ", element=" << element
+                 << ": failed: reuse of MediaSource object URL by disabling "
+                    "RevokeMediaSourceObjectURLOnAttach is not supported for "
+                    "MSE-in-Workers";
+      }
       *success = false;
       return nullptr;
     }
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc
index 399b531..8924ad712 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -1437,16 +1437,16 @@
 bool MediaSource::HasPendingActivity() const {
   // Note that an unrevoked MediaSource objectUrl for an otherwise inactive,
   // unreferenced HTMLME with MSE still attached will prevent GC of the whole
-  // group of objects. This is unfortunate, because it's conceivable that the
-  // app may actually still have a "reference" to the underlying MediaSource if
-  // it has the objectUrl in a string somewhere, for example. This is yet
-  // further motivation for apps to properly revokeObjectUrl and for the MSE
-  // spec, implementations and API users to transition to using HTMLME srcObject
-  // for MSE attachment instead of objectUrl. For at least
-  // SameThreadMediaSourceAttachments, the RevokeMediaSourceObjectURLOnAttach
-  // feature assists in automating this case. But for
-  // CrossThreadMediaSourceAttachments, the attachment holds strong references
-  // to each side until explicitly detached (or contexts destroyed).
+  // group of objects. This is yet further motivation for apps to properly
+  // revokeObjectUrl and for the MSE spec, implementations and API users to
+  // transition to using HTMLME srcObject for MSE attachment instead of
+  // objectUrl. For at least SameThreadMediaSourceAttachments, the
+  // RevokeMediaSourceObjectURLOnAttach feature assists in automating this case.
+  // But for CrossThreadMediaSourceAttachments, the attachment holds strong
+  // references to each side until explicitly detached (or contexts destroyed).
+  // The latter applies similarly when using MediaSourceHandle for srcObject
+  // attachment of a worker MediaSource: the handle object has a scoped_refptr
+  // to the underlying attachment until the handle is GC'ed.
   return async_event_queue_->HasPendingEvents();
 }
 
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.h b/third_party/blink/renderer/modules/mediasource/media_source.h
index 06d88de..082cf84c 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.h
+++ b/third_party/blink/renderer/modules/mediasource/media_source.h
@@ -46,9 +46,10 @@
 // HTMLMediaElement's instance to use the MSE API (also known as "attaching MSE
 // to a media element") by using a Media Source object URL as the media
 // element's src attribute or the src attribute of a <source> inside the media
-// element. A MediaSourceAttachmentSupplement encapsulates the linkage of that
-// object URL to a MediaSource instance, and allows communication between the
-// media element and the MSE API.
+// element, or by using a MediaSourceHandle for a worker-owned MediaSource as
+// the srcObject of the media element. A MediaSourceAttachmentSupplement
+// encapsulates the linkage of that object URL or handle to a MediaSource
+// instance, and allows communication between the media element and the MSE API.
 class MediaSource final : public EventTargetWithInlineData,
                           public ActiveScriptWrappable<MediaSource>,
                           public ExecutionContextLifecycleObserver {
diff --git a/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.cc b/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.cc
index f59a2d6..5f83ec6 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.cc
@@ -26,8 +26,8 @@
   DVLOG(1) << __func__ << " this=" << this;
 }
 
-scoped_refptr<MediaSourceAttachment> MediaSourceHandleImpl::GetAttachment() {
-  return attachment_;
+scoped_refptr<MediaSourceAttachment> MediaSourceHandleImpl::TakeAttachment() {
+  return std::move(attachment_);
 }
 
 String MediaSourceHandleImpl::GetInternalBlobURL() {
@@ -37,6 +37,13 @@
 void MediaSourceHandleImpl::mark_serialized() {
   DCHECK(!serialized_);
   serialized_ = true;
+
+  // Before being serialized, the serialization must have retrieved our
+  // reference to the |attachment_| precisely once. Note that immediately upon
+  // an instance of us being assigned to srcObject, that instance can no longer
+  // be serialized and there will be at most one async media element load that
+  // retrieves our attachment reference.
+  DCHECK(!attachment_);
 }
 
 void MediaSourceHandleImpl::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h b/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h
index 62bf6247..bd5ab93 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h
+++ b/third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h
@@ -23,7 +23,7 @@
       String internal_blob_url);
   ~MediaSourceHandleImpl() override;
 
-  scoped_refptr<MediaSourceAttachment> GetAttachment() override;
+  scoped_refptr<MediaSourceAttachment> TakeAttachment() override;
   String GetInternalBlobURL() override;
 
   void mark_serialized();
diff --git a/third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h b/third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h
index e4566d2c..1bd9268 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h
+++ b/third_party/blink/renderer/modules/mediasource/media_source_registry_impl.h
@@ -20,6 +20,9 @@
 // This singleton lives on the main thread. It allows registration and
 // deregistration of MediaSource objectUrls from both main and dedicated worker
 // threads, internally locking to access or update |media_sources_| coherently.
+// TODO(crbug.com/878133): Completely remove the ability to use this from
+// dedicated worker threads once MediaSourceInWorkersUsingHandle has shipped
+// stable.
 class MediaSourceRegistryImpl final : public MediaSourceRegistry {
  public:
   // Creates the singleton instance. Must be run on the main thread (expected to
diff --git a/third_party/blink/renderer/modules/mediasource/url_media_source.cc b/third_party/blink/renderer/modules/mediasource/url_media_source.cc
index 783f178..4854bf6c 100644
--- a/third_party/blink/renderer/modules/mediasource/url_media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/url_media_source.cc
@@ -50,25 +50,41 @@
                                        MediaSource* source) {
   // Since WebWorkers previously could not obtain MediaSource objects, we should
   // be on the main thread unless MediaSourceInWorkers is enabled and we're in a
-  // dedicated worker execution context.
+  // dedicated worker execution context. Even in that case, we must prevent real
+  // object URL creation+registration here if MediaSourceInWorkersUsingHandle is
+  // enabled, since in that case, MediaSourceHandle is the exclusive attachment
+  // mechanism for a worker-owned MediaSource.
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
   DCHECK(execution_context);
   DCHECK(IsMainThread() || RuntimeEnabledFeatures::MediaSourceInWorkersEnabled(
                                execution_context));
   DCHECK(source);
 
+  UseCounter::Count(execution_context, WebFeature::kCreateObjectURLMediaSource);
+
   MediaSourceAttachment* attachment;
   if (execution_context->IsDedicatedWorkerGlobalScope()) {
     // TODO(crbug.com/878133): Disallow this code path (CTMSA in object URL),
     // instead use CTMSA via MediaSourceHandleImpl.
     DCHECK(!IsMainThread());
 
+    UseCounter::Count(execution_context,
+                      WebFeature::kCreateObjectURLMediaSourceFromWorker);
+    if (RuntimeEnabledFeatures::MediaSourceInWorkersUsingHandleEnabled(
+            execution_context)) {
+      // Return empty string, which if attempted to be used as media element src
+      // by the app will cause the required failure. Note that the partial
+      // interface for this method in WebIDL must have same exposure as the
+      // extended createObjectURL interface, so we cannot simply remove this
+      // partial interface from exposure on dedicated workers even once
+      // MediaSourceInWorkersUsingHandle is shipped stable.
+      return String();
+    }
+
     // PassKey provider usage here ensures that we are allowed to call the
     // attachment constructor.
     attachment = new CrossThreadMediaSourceAttachment(
         source, AttachmentCreationPassKeyProvider::GetPassKey());
-    UseCounter::Count(execution_context,
-                      WebFeature::kCreateObjectURLMediaSourceFromWorker);
   } else {
     // Other contexts outside of main window thread or conditionally a dedicated
     // worker thread are not supported (like Shared Worker and Service Worker).
@@ -80,8 +96,6 @@
         source, AttachmentCreationPassKeyProvider::GetPassKey());
   }
 
-  UseCounter::Count(execution_context, WebFeature::kCreateObjectURLMediaSource);
-
   // The creation of a ThreadSafeRefCounted attachment object, above, should
   // have a refcount of 1 immediately. It will be adopted into a scoped_refptr
   // in MediaSourceRegistryImpl::RegisterURL. See also MediaSourceAttachment
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc
index b409cb2c..135b345 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -592,7 +592,7 @@
   if (SendErrorIsFatal(error))
     write_fatal_ = true;
   if (underlying_sink_)
-    underlying_sink_->SignalErrorOnClose(DOMExceptionFromSendError(error));
+    underlying_sink_->SignalError(DOMExceptionFromSendError(error));
 }
 
 bool SerialPort::CreateDataPipe(mojo::ScopedDataPipeProducerHandle* producer,
@@ -640,7 +640,7 @@
   }
 
   if (underlying_sink_) {
-    underlying_sink_->SignalErrorOnClose(
+    underlying_sink_->SignalError(
         DOMExceptionFromSendError(SerialSendError::DISCONNECTED));
   }
 }
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
index b6bcad03..0421cb61 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -33,6 +33,7 @@
     ScriptState* script_state,
     WritableStreamDefaultController* controller,
     ExceptionState& exception_state) {
+  script_state_ = script_state;
   controller_ = controller;
 
   class AbortAlgorithm final : public AbortSignal::Algorithm {
@@ -66,15 +67,6 @@
   DCHECK_EQ(0u, offset_);
   DCHECK(!pending_operation_);
 
-  if (pending_exception_) {
-    exception_state.RethrowV8Exception(
-        ToV8Traits<DOMException>::ToV8(script_state, pending_exception_)
-            .ToLocalChecked());
-    pending_exception_ = nullptr;
-    serial_port_->UnderlyingSinkClosed();
-    return ScriptPromise();
-  }
-
   buffer_source_ = V8BufferSource::Create(script_state->GetIsolate(),
                                           chunk.V8Value(), exception_state);
   if (exception_state.HadException())
@@ -97,15 +89,6 @@
   watcher_.Cancel();
   data_pipe_.reset();
 
-  if (pending_exception_) {
-    exception_state.RethrowV8Exception(
-        ToV8Traits<DOMException>::ToV8(script_state, pending_exception_)
-            .ToLocalChecked());
-    pending_exception_ = nullptr;
-    serial_port_->UnderlyingSinkClosed();
-    return ScriptPromise();
-  }
-
   pending_operation_ =
       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   serial_port_->Drain(WTF::Bind(&SerialPortUnderlyingSink::OnFlushOrDrain,
@@ -123,15 +106,6 @@
   watcher_.Cancel();
   data_pipe_.reset();
 
-  if (pending_exception_) {
-    exception_state.RethrowV8Exception(
-        ToV8Traits<DOMException>::ToV8(script_state, pending_exception_)
-            .ToLocalChecked());
-    pending_exception_ = nullptr;
-    serial_port_->UnderlyingSinkClosed();
-    return ScriptPromise();
-  }
-
   // If the port is closing the flush will be performed when it closes so we
   // don't need to do it here.
   if (serial_port_->IsClosing()) {
@@ -147,25 +121,26 @@
   return pending_operation_->Promise();
 }
 
-void SerialPortUnderlyingSink::SignalErrorOnClose(DOMException* exception) {
-  if (data_pipe_ || !pending_operation_) {
-    // Pipe is still open or we don't have a write operation that can be failed.
-    // Wait for PipeClosed() to be called.
-    pending_exception_ = exception;
-    return;
-  }
+void SerialPortUnderlyingSink::SignalError(DOMException* exception) {
+  watcher_.Cancel();
+  data_pipe_.reset();
 
   if (pending_operation_) {
     pending_operation_->Reject(exception);
     pending_operation_ = nullptr;
-    serial_port_->UnderlyingSinkClosed();
+  } else {
+    ScriptState::Scope scope(script_state_);
+    controller_->error(script_state_,
+                       ScriptValue::From(script_state_, exception));
   }
+
+  serial_port_->UnderlyingSinkClosed();
 }
 
 void SerialPortUnderlyingSink::Trace(Visitor* visitor) const {
   visitor->Trace(serial_port_);
+  visitor->Trace(script_state_);
   visitor->Trace(controller_);
-  visitor->Trace(pending_exception_);
   visitor->Trace(buffer_source_);
   visitor->Trace(pending_operation_);
   UnderlyingSinkBase::Trace(visitor);
@@ -200,14 +175,8 @@
 void SerialPortUnderlyingSink::OnFlushOrDrain() {
   DCHECK(pending_operation_);
 
-  if (pending_exception_) {
-    pending_operation_->Reject(pending_exception_);
-    pending_exception_ = nullptr;
-  } else {
-    pending_operation_->Resolve();
-  }
+  pending_operation_->Resolve();
   pending_operation_ = nullptr;
-
   serial_port_->UnderlyingSinkClosed();
 }
 
@@ -260,18 +229,8 @@
 }
 
 void SerialPortUnderlyingSink::PipeClosed() {
-  DCHECK(pending_operation_);
-
   watcher_.Cancel();
   data_pipe_.reset();
-
-  if (pending_exception_) {
-    pending_operation_->Reject(pending_exception_);
-    pending_operation_ = nullptr;
-    pending_exception_ = nullptr;
-
-    serial_port_->UnderlyingSinkClosed();
-  }
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
index 2b1ff5b5..9a08bb4b 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h
@@ -34,9 +34,7 @@
                       ScriptValue reason,
                       ExceptionState&) override;
 
-  // After |data_pipe_| has closed calls to write() will return a Promise
-  // rejected with this DOMException.
-  void SignalErrorOnClose(DOMException*);
+  void SignalError(DOMException*);
 
   void Trace(Visitor*) const override;
 
@@ -50,8 +48,8 @@
   mojo::ScopedDataPipeProducerHandle data_pipe_;
   mojo::SimpleWatcher watcher_;
   Member<SerialPort> serial_port_;
+  Member<ScriptState> script_state_;
   Member<WritableStreamDefaultController> controller_;
-  Member<DOMException> pending_exception_;
 
   Member<V8BufferSource> buffer_source_;
   size_t offset_ = 0;
diff --git a/third_party/blink/renderer/modules/shared_storage/DEPS b/third_party/blink/renderer/modules/shared_storage/DEPS
index 25fddd4..36f89b6 100644
--- a/third_party/blink/renderer/modules/shared_storage/DEPS
+++ b/third_party/blink/renderer/modules/shared_storage/DEPS
@@ -5,4 +5,5 @@
     "+third_party/blink/renderer/modules/shared_storage",
     "+third_party/blink/renderer/modules/v8",
     "+third_party/blink/renderer/core",
+    "+gin/converter.h",
 ]
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage.cc
index 98ff373..3f14882 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage.cc
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/shared_storage/shared_storage_utils.h"
+#include "third_party/blink/public/mojom/shared_storage/shared_storage.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
@@ -22,6 +23,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_run_operation_method_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_set_method_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -96,6 +98,31 @@
   resolver->Resolve();
 }
 
+// TODO(crbug.com/1335504): Consider moving this function to
+// third_party/blink/common/fenced_frame/fenced_frame_utils.cc.
+bool IsValidFencedFrameReportingURL(const KURL& url) {
+  if (!url.IsValid())
+    return false;
+  return url.ProtocolIs("https");
+}
+
+bool StringFromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, String* out) {
+  DCHECK(out);
+
+  if (!val->IsString())
+    return false;
+
+  v8::Local<v8::String> str = v8::Local<v8::String>::Cast(val);
+  wtf_size_t length = str->Utf8Length(isolate);
+  LChar* buffer;
+  *out = String::CreateUninitialized(length, buffer);
+
+  str->WriteUtf8(isolate, reinterpret_cast<char*>(buffer), length, nullptr,
+                 v8::String::NO_NULL_TERMINATION);
+
+  return true;
+}
+
 }  // namespace
 
 SharedStorage::SharedStorage() = default;
@@ -251,10 +278,11 @@
   return promise;
 }
 
-ScriptPromise SharedStorage::selectURL(ScriptState* script_state,
-                                       const String& name,
-                                       const Vector<String>& urls,
-                                       ExceptionState& exception_state) {
+ScriptPromise SharedStorage::selectURL(
+    ScriptState* script_state,
+    const String& name,
+    HeapVector<Member<SharedStorageUrlWithMetadata>> urls,
+    ExceptionState& exception_state) {
   return selectURL(script_state, name, urls,
                    SharedStorageRunOperationMethodOptions::Create(),
                    exception_state);
@@ -263,7 +291,7 @@
 ScriptPromise SharedStorage::selectURL(
     ScriptState* script_state,
     const String& name,
-    const Vector<String>& urls,
+    HeapVector<Member<SharedStorageUrlWithMetadata>> urls,
     const SharedStorageRunOperationMethodOptions* options,
     ExceptionState& exception_state) {
   ExecutionContext* execution_context = ExecutionContext::From(script_state);
@@ -297,19 +325,94 @@
     return promise;
   }
 
-  Vector<KURL> converted_urls;
+  v8::Local<v8::Context> v8_context =
+      script_state->GetIsolate()->GetCurrentContext();
+
+  Vector<mojom::blink::SharedStorageUrlWithMetadataPtr> converted_urls;
   converted_urls.ReserveInitialCapacity(urls.size());
 
-  for (const String& url : urls) {
-    KURL converted_url = execution_context->CompleteURL(url);
+  wtf_size_t index = 0;
+  for (const auto& url_with_metadata : urls) {
+    DCHECK(url_with_metadata->hasUrl());
+
+    KURL converted_url =
+        execution_context->CompleteURL(url_with_metadata->url());
+
+    // TODO(crbug.com/1318970): Use `IsValidFencedFrameURL()` or equivalent
+    // logic here.
     if (!converted_url.IsValid()) {
       resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
           script_state->GetIsolate(), DOMExceptionCode::kDataError,
-          "The url \"" + url + "\" is invalid."));
+          "The url \"" + url_with_metadata->url() + "\" is invalid."));
       return promise;
     }
 
-    converted_urls.push_back(converted_url);
+    HashMap<String, KURL> converted_reporting_metadata;
+
+    if (url_with_metadata->hasReportingMetadata()) {
+      DCHECK(url_with_metadata->reportingMetadata().V8Value()->IsObject());
+
+      v8::Local<v8::Object> obj =
+          url_with_metadata->reportingMetadata().V8Value().As<v8::Object>();
+
+      v8::MaybeLocal<v8::Array> maybe_fields =
+          obj->GetOwnPropertyNames(v8_context);
+      v8::Local<v8::Array> fields;
+      if (!maybe_fields.ToLocal(&fields) || fields->Length() == 0) {
+        resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+            script_state->GetIsolate(), DOMExceptionCode::kDataError,
+            "selectURL could not get reporting_metadata object attributes"));
+        return promise;
+      }
+
+      converted_reporting_metadata.ReserveCapacityForSize(fields->Length());
+
+      for (wtf_size_t idx = 0; idx < fields->Length(); idx++) {
+        v8::Local<v8::Value> report_event =
+            fields->Get(v8_context, idx).ToLocalChecked();
+        String report_event_string;
+        if (!StringFromV8(script_state->GetIsolate(), report_event,
+                          &report_event_string)) {
+          resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+              script_state->GetIsolate(), DOMExceptionCode::kDataError,
+              "selectURL reporting_metadata object attributes must be "
+              "strings"));
+          return promise;
+        }
+
+        v8::Local<v8::Value> report_url =
+            obj->Get(v8_context, report_event).ToLocalChecked();
+        String report_url_string;
+        if (!StringFromV8(script_state->GetIsolate(), report_url,
+                          &report_url_string)) {
+          resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+              script_state->GetIsolate(), DOMExceptionCode::kDataError,
+              "selectURL reporting_metadata object attributes must be "
+              "strings"));
+          return promise;
+        }
+
+        KURL converted_report_url =
+            execution_context->CompleteURL(report_url_string);
+
+        if (!IsValidFencedFrameReportingURL(converted_report_url)) {
+          resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+              script_state->GetIsolate(), DOMExceptionCode::kDataError,
+              "The metadata for the url at index " +
+                  String::NumberToStringECMAScript(index) +
+                  " has an invalid or non-HTTPS report_url parameter \"" +
+                  report_url_string + "\"."));
+          return promise;
+        }
+
+        converted_reporting_metadata.Set(report_event_string,
+                                         converted_report_url);
+      }
+    }
+
+    converted_urls.push_back(mojom::blink::SharedStorageUrlWithMetadata::New(
+        converted_url, std::move(converted_reporting_metadata)));
+    index++;
   }
 
   Vector<uint8_t> serialized_data;
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage.h b/third_party/blink/renderer/modules/shared_storage/shared_storage.h
index c3d0a7f5..1a6f4110 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage.h
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage.h
@@ -21,6 +21,7 @@
 class SharedStorageWorklet;
 class SharedStorageSetMethodOptions;
 class SharedStorageRunOperationMethodOptions;
+class SharedStorageUrlWithMetadata;
 
 class MODULES_EXPORT SharedStorage final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -53,11 +54,11 @@
 
   ScriptPromise selectURL(ScriptState*,
                           const String& name,
-                          const Vector<String>& urls,
+                          HeapVector<Member<SharedStorageUrlWithMetadata>> urls,
                           ExceptionState&);
   ScriptPromise selectURL(ScriptState*,
                           const String& name,
-                          const Vector<String>& urls,
+                          HeapVector<Member<SharedStorageUrlWithMetadata>> urls,
                           const SharedStorageRunOperationMethodOptions* options,
                           ExceptionState&);
 
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage.idl b/third_party/blink/renderer/modules/shared_storage/shared_storage.idl
index c09e7b7..cf7214d 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage.idl
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage.idl
@@ -33,7 +33,8 @@
     CallWith=ScriptState,
     RaisesException,
     MeasureAs=SharedStorageAPI_SelectURL_Method
-  ] Promise<USVString> selectURL(DOMString name, FrozenArray<USVString> urls,
+  ] Promise<USVString> selectURL(DOMString name,
+                                 FrozenArray<SharedStorageUrlWithMetadata> urls,
                                  optional SharedStorageRunOperationMethodOptions options);
 
   [
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_url_with_metadata.idl b/third_party/blink/renderer/modules/shared_storage/shared_storage_url_with_metadata.idl
new file mode 100644
index 0000000..b82e481
--- /dev/null
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_url_with_metadata.idl
@@ -0,0 +1,4 @@
+dictionary SharedStorageUrlWithMetadata {
+  required USVString url;
+  object reporting_metadata;
+};
diff --git a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
index 1017b6c..740cdcb 100644
--- a/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -122,7 +122,8 @@
 #else
         base::PartitionOptions::ThreadCache::kEnabled;
 #endif
-    static base::NoDestructor<base::PartitionAllocator> fast_malloc_allocator{};
+    static base::NoDestructor<partition_alloc::PartitionAllocator>
+        fast_malloc_allocator{};
     fast_malloc_allocator->init({
         base::PartitionOptions::AlignedAlloc::kDisallowed,
         thread_cache,
@@ -134,9 +135,10 @@
     fast_malloc_root_ = fast_malloc_allocator->root();
   }
 
-  base::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory);
+  partition_alloc::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory);
 
-  static base::NoDestructor<base::PartitionAllocator> buffer_allocator{};
+  static base::NoDestructor<partition_alloc::PartitionAllocator>
+      buffer_allocator{};
   buffer_allocator->init({
       base::PartitionOptions::AlignedAlloc::kDisallowed,
       base::PartitionOptions::ThreadCache::kDisabled,
@@ -177,7 +179,8 @@
   CHECK(initialized_);
   CHECK(!ArrayBufferPartitionInitialized());
 
-  static base::NoDestructor<base::PartitionAllocator> array_buffer_allocator{};
+  static base::NoDestructor<partition_alloc::PartitionAllocator>
+      array_buffer_allocator{};
 
   // BackupRefPtr disallowed because it will prevent allocations from being 16B
   // aligned as required by ArrayBufferContents.
@@ -248,13 +251,13 @@
 
   void PartitionDumpTotals(
       const char* partition_name,
-      const base::PartitionMemoryStats* memory_stats) override {
+      const partition_alloc::PartitionMemoryStats* memory_stats) override {
     total_active_bytes_ += memory_stats->total_active_bytes;
   }
 
   void PartitionsDumpBucketStats(
       const char* partition_name,
-      const base::PartitionBucketMemoryStats*) override {}
+      const partition_alloc::PartitionBucketMemoryStats*) override {}
 
   size_t TotalActiveBytes() const { return total_active_bytes_; }
 
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
index 27b40787..870ae100 100644
--- a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
+++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -154,8 +154,8 @@
                                          builder_name)
 
     @memoized
-    def fetch_retry_summary_json(self, build):
-        """Fetches and returns the text of the archived test_results_summary.json file.
+    def fetch_retry_summary_json(self, build, test_suite):
+        """Fetches and returns the text of the archived *test_results_summary.json file.
 
         This file is expected to contain the results of retrying web tests
         with and without a patch in a try job. It includes lists of tests
@@ -169,8 +169,9 @@
         # accessed via test-results, so we download it from GCS directly.
         # There is still a bug in uploading this json file for other platforms than linux.
         # see https://crbug.com/1157202
+        file_name = test_suite + '_' + 'test_results_summary.json'
         return self.web.get_binary('%s/%s' %
-                                   (url_base, 'test_results_summary.json'),
+                                   (url_base, file_name),
                                    return_none_on_404=True)
 
     def accumulated_results_url_base(self, builder_name):
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py
index 514c923c..1b516fc 100644
--- a/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py
+++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher_mock.py
@@ -88,7 +88,7 @@
     def set_retry_sumary_json(self, build, content):
         self._canned_retry_summary_json[build] = content
 
-    def fetch_retry_summary_json(self, build):
+    def fetch_retry_summary_json(self, build, test_suite):
         return self._canned_retry_summary_json.get(build)
 
     def get_layout_test_step_names(self, build):
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
index d2b38c1..6b60bfb 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
@@ -8,6 +8,7 @@
 import json
 import logging
 import optparse
+import re
 
 from blinkpy.common.net.git_cl import GitCL, TryJobStatus
 from blinkpy.common.path_finder import PathFinder
@@ -473,7 +474,8 @@
             r.test_name() for r in unexpected_results
             if r.is_missing_baseline() or r.has_non_reftest_mismatch())
 
-        new_failures = self._fetch_tests_with_new_failures(build)
+        test_suite = re.sub('\s*\(.*\)$', '', web_test_results.step_name())
+        new_failures = self._fetch_tests_with_new_failures(build, test_suite)
         if new_failures is None:
             _log.warning('No retry summary available for "%s".',
                          build.builder_name)
@@ -481,8 +483,9 @@
             tests = [t for t in tests if t in new_failures]
         return tests
 
-    def _fetch_tests_with_new_failures(self, build):
-        """For a given try job, lists tests that only failed with the patch.
+    def _fetch_tests_with_new_failures(self, build, test_suite):
+        """For a given test suite in the try job, lists tests that only failed
+        with the patch.
 
         If a test failed only with the patch but not without, then that
         indicates that the failure is actually related to the patch and
@@ -491,7 +494,7 @@
         If the list of new failures could not be obtained, this returns None.
         """
         results_fetcher = self._tool.results_fetcher
-        content = results_fetcher.fetch_retry_summary_json(build)
+        content = results_fetcher.fetch_retry_summary_json(build, test_suite)
         if content is None:
             return None
         try:
diff --git a/third_party/blink/tools/run_blinkpy_tests.py b/third_party/blink/tools/run_blinkpy_tests.py
index 0b83cce..43d341f 100755
--- a/third_party/blink/tools/run_blinkpy_tests.py
+++ b/third_party/blink/tools/run_blinkpy_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env vpython
+#!/usr/bin/env vpython3
 # Copyright (c) 2011 Google Inc. All rights reserved.
 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
 #
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 20af476..9e349789 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 9894fff50b438d61b269e559ac004ba515f72637
+Version: 3f4defa10692e126bb0e4d44a419ba17ff77c74b
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 122bbc4..1bf1280e 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -3030,6 +3030,13 @@
      ]
     },
     "filter-effects": {
+     "backdrop-filter-feimage-crash.html": [
+      "762452e8e604c8c57b06c67d58b069720decc1ad",
+      [
+       null,
+       {}
+      ]
+     ],
      "crashtests": {
       "broken-reference-crash-001.html": [
        "6e18e06c317e329a58b2b5132cf17dc6086d444f",
@@ -13664,6 +13671,13 @@
        }
       },
       "the-input-element": {
+       "disabled-click-picker-manual.html": [
+        "b77f981e6c19e0f91e367cf8d1808f11acac83b3",
+        [
+         null,
+         {}
+        ]
+       ],
        "event-select-manual.html": [
         "ed0b21e9f30db0e7d1e01659fcf17e6cf17709d0",
         [
@@ -96989,7 +97003,7 @@
      ],
      "container-queries": {
       "canvas-as-container-001.html": [
-       "2f0c5f4827cadd5b9d7c50a1e71f27e97a966d4a",
+       "f904d1fe249bb3ad773f054b7f930deba36eccce",
        [
         null,
         [
@@ -97002,7 +97016,7 @@
        ]
       ],
       "canvas-as-container-002.html": [
-       "0638d1e648656ce5cddc007663e701f7c950a49a",
+       "689feeb5fffdc25ccd03e41c29a317ad1018ced2",
        [
         null,
         [
@@ -97015,7 +97029,7 @@
        ]
       ],
       "canvas-as-container-003.html": [
-       "7c2651ff46915d0467b315aa21196c205ae56bf1",
+       "74199cc72b7e68b8d51eb783439e58e12f4ee867",
        [
         null,
         [
@@ -97028,7 +97042,7 @@
        ]
       ],
       "canvas-as-container-004.html": [
-       "d9b661c0f95e998cbfe79359cfd1fa7ca10949c2",
+       "b23846382b743d260ea87a291dec31af843c16e9",
        [
         null,
         [
@@ -180678,7 +180692,7 @@
       ]
      ],
      "text-decoration-thickness-fixed.html": [
-      "3437c430d8334d3be255a1eba6e6bd2a34d97449",
+      "07dab0b9b659e43af404c51d4e8b038915a71df5",
       [
        null,
        [
@@ -231069,6 +231083,283 @@
          ]
         ]
        },
+       "layers": {
+        "layers-alpha-filter-globalcompositeoperation.html": [
+         "6912d6a18b4475b20ab590841886f5d814ceb05d",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-alpha-filter-globalcompositeoperation-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-alpha-filter-shadow.html": [
+         "9c4a6fcaa7e7a34132120ca8d3ef4a442a669d44",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-alpha-filter-shadow-expected.html",
+            "=="
+           ]
+          ],
+          {
+           "fuzzy": [
+            [
+             null,
+             [
+              [
+               0,
+               2
+              ],
+              [
+               0,
+               18000
+              ]
+             ]
+            ]
+           ]
+          }
+         ]
+        ],
+        "layers-alpha-filter.html": [
+         "7a895cf34dc00b1d848365649e8d7ed1f64e40c4",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-alpha-filter-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-alpha-shadow.html": [
+         "e7d791d8fc076528d31e8e1d70477c2acd364b34",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-alpha-shadow-expected.html",
+            "=="
+           ]
+          ],
+          {
+           "fuzzy": [
+            [
+             null,
+             [
+              [
+               0,
+               2
+              ],
+              [
+               0,
+               18000
+              ]
+             ]
+            ]
+           ]
+          }
+         ]
+        ],
+        "layers-alpha.html": [
+         "7be5bdb0bb89faf078520d10b3362a277ce9e801",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-alpha-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-endlayer-noop.html": [
+         "aae72cfeaefc80f24c2894a98f233d47f2aad8bd",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-endlayer-noop-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-filter-globalcompositeoperation.html": [
+         "03d04d09ae5cb816ab310940d5c8746a7682a1dc",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-filter-globalcompositeoperation-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-filter-shadow.html": [
+         "31ce671629027fd8bbd00bf8350eb556e86544ca",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-filter-shadow-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-filter.html": [
+         "c4d63cda2ff9481a6a39cc7b4ada910aa4303a49",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-filter-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-globalcompositeoperation.html": [
+         "6d4fde3ed5367ff7137f6b77b8066ce2953d6d94",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-globalcompositeoperation-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-loneendlayer.html": [
+         "f0584d385cc69c3eeb97f6df43f45a721961bfb7",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-loneendlayer-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "layers-nested.html": [
+         "fb52976ac8a44b197bc448d799ff06a8024085ab",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-nested-expected.html",
+            "=="
+           ]
+          ],
+          {
+           "fuzzy": [
+            [
+             null,
+             [
+              [
+               0,
+               2
+              ],
+              [
+               0,
+               14000
+              ]
+             ]
+            ]
+           ]
+          }
+         ]
+        ],
+        "layers-restorestyle.html": [
+         "659b6c0ba05ce46a278414da300b3de5229f6da7",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-restorestyle-expected.html",
+            "=="
+           ]
+          ],
+          {
+           "fuzzy": [
+            [
+             null,
+             [
+              [
+               0,
+               1
+              ],
+              [
+               0,
+               14000
+              ]
+             ]
+            ]
+           ]
+          }
+         ]
+        ],
+        "layers-several-complex.html": [
+         "66840bbab951aaea6cfb10c6896bf689133fa74f",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-several-complex-expected.html",
+            "=="
+           ]
+          ],
+          {
+           "fuzzy": [
+            [
+             null,
+             [
+              [
+               0,
+               3
+              ],
+              [
+               0,
+               19000
+              ]
+             ]
+            ]
+           ]
+          }
+         ]
+        ],
+        "layers-shadow.html": [
+         "59768746e49e25240e3f4083a196db04f60edebc",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/layers/layers-shadow-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ]
+       },
        "line-styles": {
         "canvas_linestyles_linecap_001.htm": [
          "583dbc9d134682a778569877e38513e07736dd82",
@@ -252545,7 +252836,7 @@
       []
      ],
      "cookie-test.js": [
-      "7c3b8619eeafac3885c69917e3cc5d0687d8f73e",
+      "c73d4d756dcbb05185d6e69ab6316d3afba9d8cb",
       []
      ],
      "cookie.py": [
@@ -287568,7 +287859,7 @@
        []
       ],
       "text-decoration-thickness-fixed-ref.html": [
-       "b155eb9c8a01de0165b0515c1a88fbe7424416bc",
+       "88f7b46843a6f8694b740ce18f04b5206ae5e15f",
        []
       ],
       "text-decoration-thickness-from-font-variable-ref.html": [
@@ -302468,17 +302759,13 @@
          []
         ],
         "helper.sub.js": [
-         "4b42d91670252f929306fcda2e34dd4e61ea3265",
+         "ff446f5ee9d3c884f9867f05d2f736d3c752b100",
          []
         ],
         "inflight-fetch-helper.js": [
          "7832003b76b9518d5f3588bb5e9f6e0dbd8cea07",
          []
         ],
-        "service-worker.js": [
-         "60dceb0a6a6f5f2cf882610e3bd19e15e9533458",
-         []
-        ],
         "slow.py": [
          "01bb3309b103d5bba772bdbf1d0d0b8bc28c8e99",
          []
@@ -305036,123 +305323,63 @@
        },
        "layers": {
         "layers-alpha-expected.html": [
-         "876eacc0b4ed9aa33768241bb31bbb71f4c43ba9",
+         "03fe48a3a2078c344d8e95004cf954195d8a9ead",
          []
         ],
         "layers-alpha-filter-expected.html": [
-         "bd0affb3f7b1674716f510c1ab0882d838d54930",
+         "5b54384a79bfaf43470bc5639f42d7b04fb1e82b",
          []
         ],
         "layers-alpha-filter-globalcompositeoperation-expected.html": [
-         "bd9b5aec0832894c3939ebee2746071d3c892d5e",
-         []
-        ],
-        "layers-alpha-filter-globalcompositeoperation.html": [
-         "dd1af3db8159ce23cb871cc556df2eb5e264bf4e",
+         "8d84dcb73f4f5778a895ae2ab56fb8bcc9a02cd6",
          []
         ],
         "layers-alpha-filter-shadow-expected.html": [
-         "bfdb26e0e86458b857f0d151a6a4b9ac7d65dc43",
-         []
-        ],
-        "layers-alpha-filter-shadow.html": [
-         "ae97240024dd10abe5c0d2808b2325b771a2bd0b",
-         []
-        ],
-        "layers-alpha-filter.html": [
-         "d45b1d5ce628c4fb0fdc4024a689a8ec03472d7f",
+         "89c3f64feae4dde06a8e047ba35d5098c08eff6f",
          []
         ],
         "layers-alpha-shadow-expected.html": [
-         "89343e787d4b99be512a1cdc31f7b409814958cc",
-         []
-        ],
-        "layers-alpha-shadow.html": [
-         "bfe7241bd2ff78e9383429ef7311a71980425749",
-         []
-        ],
-        "layers-alpha.html": [
-         "fe871e7e2d07c95a4022122bd57971a73d30ebf5",
+         "f29fb736e3ab38f6179acb1aed63973e040b9c19",
          []
         ],
         "layers-endlayer-noop-expected.html": [
-         "e3c9571fd4477b3dede65a2bfbaaa43571bec48a",
-         []
-        ],
-        "layers-endlayer-noop.html": [
-         "d9d620073fda029c79ab6a872062fc1e2dee73d4",
+         "7f4937ecda40e2aa85864e518caf9bd48d870cb9",
          []
         ],
         "layers-filter-expected.html": [
-         "a65f52b770cb68e51aa1d77844029ce5c15a5e6f",
+         "7fe4d2c03efc5635ab42ca307fd693f24b05a267",
          []
         ],
         "layers-filter-globalcompositeoperation-expected.html": [
-         "3e9fbee643beb9a54d4cfbedfdd0cbb074bbb3ad",
-         []
-        ],
-        "layers-filter-globalcompositeoperation.html": [
-         "51c79c86c7ca2518603026126c558537cfd3143a",
+         "0676d7e1aac001ba89c5e4fafd7dc1d216f4cf41",
          []
         ],
         "layers-filter-shadow-expected.html": [
-         "85a5bea8b8fa1e16bf64feec662a32022ca77a78",
-         []
-        ],
-        "layers-filter-shadow.html": [
-         "e4da5b81042bc5ab174477f130f78c64656e43bd",
-         []
-        ],
-        "layers-filter.html": [
-         "9dbb09f6ee99e29bdc1998bf2c103ef920f2846e",
+         "5d141c3d0856e29d35e2a75efeba830522e3cf91",
          []
         ],
         "layers-globalcompositeoperation-expected.html": [
-         "234c1f9e2de25c38e22319b8d19201613490b0bf",
-         []
-        ],
-        "layers-globalcompositeoperation.html": [
-         "20ce0ca2c27edc282a30bb9175d44a0fc49d5f03",
+         "d2d4317f0742eea23ff50abd45d6fa9a98dd26c6",
          []
         ],
         "layers-loneendlayer-expected.html": [
-         "d6e06cda1aed040d3b20f395074c7c87ae21dbcb",
-         []
-        ],
-        "layers-loneendlayer.html": [
-         "e762c5f1fb76fcb264b503a242e97753f6f39ae4",
+         "cec5a54512c5782ce1574c6d4d191e483b776e26",
          []
         ],
         "layers-nested-expected.html": [
-         "c74f1e64956874f2ddde6ba3bd0e2156615c0e35",
-         []
-        ],
-        "layers-nested.html": [
-         "b1bbdbeba5fa95310112db411f95fc2ba5624624",
+         "4647996adfc69b24ab3fb4779db03c6b987f36ba",
          []
         ],
         "layers-restorestyle-expected.html": [
-         "6372dfe62e97ed25ab92c8762372f6572fe9e028",
-         []
-        ],
-        "layers-restorestyle.html": [
-         "9a20aa07710744a5a7a28e58734026de63fb07af",
+         "f67a4571171ad5aae970c042e482395fa5f22870",
          []
         ],
         "layers-several-complex-expected.html": [
-         "60fffec0c0b545ad0d2c4c0d90b96266ff004401",
-         []
-        ],
-        "layers-several-complex.html": [
-         "586e1f07e764dd62bdf18a5d27064e37bec83400",
+         "eca81cd8d72ce689d2635532b08b31de667aa1c8",
          []
         ],
         "layers-shadow-expected.html": [
-         "c58bc5063e385dbd7626590342aadae2aab7b4e2",
-         []
-        ],
-        "layers-shadow.html": [
-         "a605ef498719d71952bd44a353be4f3828c3635c",
+         "76960455719cdad63809e3733ef7154e0da64f3f",
          []
         ]
        },
@@ -368429,7 +368656,7 @@
       ]
      ],
      "expires.html": [
-      "f61c4057fdafa65afbf8b15d9ddbd2e673299d54",
+      "a6bacfd74e97db1db1a68596a6f65f0a15e4a542",
       [
        null,
        {
@@ -372277,6 +372504,13 @@
        {}
       ]
      ],
+     "hit-test-hidden-overflow.html": [
+      "ec766e0948470e06f2e7f4f24ed7b1e694a5c5fb",
+      [
+       null,
+       {}
+      ]
+     ],
      "hit-test-inline-fragmentation-with-border-radius.html": [
       "4d0fc7eccc45e44480b4305632ceac2068c59919",
       [
@@ -372475,7 +372709,30 @@
         null,
         {}
        ]
-      ]
+      ],
+      "repeated-section": {
+       "hit-test-relative-in-transform.tentative.html": [
+        "43a36f1853c1c7bd73c90db71141e4169e1d183a",
+        [
+         null,
+         {}
+        ]
+       ],
+       "hit-test-relative.tentative.html": [
+        "348bb0dbc483f0ed925ab6546d99d19df0141df1",
+        [
+         null,
+         {}
+        ]
+       ],
+       "hit-test.tentative.html": [
+        "9b462887c3f5875aaf22715e331ed97975a38032",
+        [
+         null,
+         {}
+        ]
+       ]
+      }
      },
      "transform-010.html": [
       "8418551cdc8172862d57d8359a732968b3467aba",
@@ -435736,42 +435993,6 @@
          }
         ]
        ],
-       "service-worker-clients-claim.https.html": [
-        "d9540c221bdf21e8e4256f30548aedbfee46e218",
-        [
-         null,
-         {
-          "timeout": "long"
-         }
-        ]
-       ],
-       "service-worker-clients-matchall.https.html": [
-        "069529dbe477c642e7396b0cd021d2f43d5e1e08",
-        [
-         null,
-         {
-          "timeout": "long"
-         }
-        ]
-       ],
-       "service-worker-controlled-after-restore.https.html": [
-        "5a63b6e677af2020bb5c414d289379c86e7b5dba",
-        [
-         null,
-         {
-          "timeout": "long"
-         }
-        ]
-       ],
-       "service-worker-unregister.https.html": [
-        "1c3f81153c2a17a3dfc719d2cccca2079525b630",
-        [
-         null,
-         {
-          "timeout": "long"
-         }
-        ]
-       ],
        "storage-events.html": [
         "6957496c3077acd5e87fa3127febfbcbbfb80099",
         [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-001.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-001.html
index 2f0c5f48..f904d1fe 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-001.html
@@ -21,5 +21,9 @@
   <div id="target" tabIndex="1"></div>
 </canvas>
 <script>
-  target.focus();
+  requestAnimationFrame(()=> {
+    requestAnimationFrame(()=> {
+      target.focus();
+    });
+  });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-002.html
index 0638d1e6..689feeb5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-002.html
@@ -22,5 +22,9 @@
   <div id="target" tabIndex="1"></div>
 </canvas>
 <script>
-  target.focus();
+  requestAnimationFrame(()=> {
+    requestAnimationFrame(()=> {
+      target.focus();
+    });
+  });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-003.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-003.html
index 7c2651f..74199cc 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-003.html
@@ -24,5 +24,9 @@
   <div id="target" tabIndex="1"></div>
 </canvas>
 <script>
-  target.focus();
+  requestAnimationFrame(()=> {
+    requestAnimationFrame(()=> {
+      target.focus();
+    });
+  });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-004.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-004.html
index d9b661c0..b238463 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/canvas-as-container-004.html
@@ -25,5 +25,9 @@
   <div id="target" tabIndex="1"></div>
 </canvas>
 <script>
-  target.focus();
+  requestAnimationFrame(()=> {
+    requestAnimationFrame(()=> {
+      target.focus();
+    });
+  });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-feimage-crash.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-feimage-crash.html
new file mode 100644
index 0000000..762452e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-feimage-crash.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1770063">
+<style>
+* {
+  backdrop-filter: url(#a);
+  filter: saturate(60%);
+}
+</style>
+<svg>
+<filter id='a'>
+<feImage>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js
index 4b42d91..ff446f5e 100644
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js
@@ -187,16 +187,3 @@
     }
   }, description);
 }
-
-// Call clients.claim() on the service worker
-async function claim(t, worker) {
-  const channel = new MessageChannel();
-  const saw_message = new Promise(function(resolve) {
-    channel.port1.onmessage = t.step_func(function(e) {
-      assert_equals(e.data, 'PASS', 'Worker call to claim() should fulfill.');
-      resolve();
-    });
-  });
-  worker.postMessage({port: channel.port2}, [channel.port2]);
-  await saw_message;
-}
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/service-worker.js b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/service-worker.js
deleted file mode 100644
index 60dceb0..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/service-worker.js
+++ /dev/null
@@ -1,31 +0,0 @@
-self.addEventListener('message', function(event) {
-    self.clients.claim()
-      .then(function(result) {
-          if (result !== undefined) {
-              event.data.port.postMessage(
-                  'FAIL: claim() should be resolved with undefined');
-              return;
-          }
-          event.data.port.postMessage('PASS');
-        })
-      .catch(function(error) {
-          event.data.port.postMessage('FAIL: exception: ' + error.name);
-        });
-  });
-
-self.addEventListener('fetch', e => {
-    if (e.request.url.match(/\/is-controlled/)) {
-      e.respondWith(new Response('controlled'));
-    }
-    else if (e.request.url.match(/\/get-clients-matchall/)) {
-      const options = { includeUncontrolled: true, type: 'all' };
-      e.respondWith(
-        self.clients.matchAll(options)
-          .then(clients => {
-            const client_urls = [];
-            clients.forEach(client => client_urls.push(client.url));
-            return new Response(JSON.stringify(client_urls));
-          })
-      );
-    }
-  });
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-claim.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-claim.https.html
deleted file mode 100644
index d9540c2..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-claim.https.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!doctype html>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/utils.js"></script>
-<script src="/common/dispatcher/dispatcher.js"></script>
-<script src="resources/helper.sub.js"></script>
-<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
-<script>
-// Calling Clients.claim() on the service worker when a controlled page is in
-// BFCache should evict the page from BFCache, as per
-// https://github.com/w3c/ServiceWorker/issues/1038#issuecomment-291028845.
-promise_test(async t => {
-  const pageA = new RemoteContext(token());
-  const pageB = new RemoteContext(token());
-
-  const urlA = location.origin + executorPath + pageA.context_id;
-  const urlB = originCrossSite + executorPath + pageB.context_id;
-
-  window.open(urlA, '_blank', 'noopener');
-  await pageA.execute_script(waitForPageShow);
-
-  // Register a service worker after `pageA` is loaded to make `pageA`
-  // uncontrolled at this time.
-  const workerUrl =
-      'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)';
-  const registration =
-      await service_worker_unregister_and_register(t, workerUrl, './');
-  t.add_cleanup(_ => registration.unregister());
-  await wait_for_state(t, registration.installing, 'activated');
-
-  // Navigate to `urlB`.
-  await pageA.execute_script(
-    (url) => {
-      prepareNavigation(() => { location.href = url; });
-    },
-    [urlB]);
-  await pageB.execute_script(waitForPageShow);
-
-  // Call Clients.claim() on the service worker when `pageA` is in BFCache.
-  const controllerChanged = new Promise(
-      resolve => navigator.serviceWorker.oncontrollerchange = resolve);
-  await claim(t, registration.active);
-  await controllerChanged;
-
-  // `pageA` doesn't appear in matchAll().
-  const clients1 = await (await fetch('/get-clients-matchall')).json();
-  assert_true(clients1.indexOf(urlA) < 0,
-              '1: matchAll() before back navigation');
-
-  // Back navigate and check that the page was evicted from BFCache.
-  await pageB.execute_script(
-    () => {
-      prepareNavigation(() => { history.back(); });
-    }
-  );
-  await pageA.execute_script(waitForPageShow);
-  await assert_not_bfcached(pageA);
-
-  // After back navigation, `pageA` appear in matchAll(), because it was newly
-  // loaded and controlled by the service worker.
-  const clients2 = await (await fetch('/get-clients-matchall')).json();
-  const controlled2 = await pageA.execute_script(
-    () => (navigator.serviceWorker.controller !== null));
-  assert_true(clients2.indexOf(urlA) >= 0,
-    '2: matchAll() just after back navigation');
-  assert_true(controlled2,
-    '2: pageA should be controlled just after back navigation');
-
-}, 'Clients.claim() evicts pages that would be affected from BFCache');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https.html
deleted file mode 100644
index 069529db..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!doctype html>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/utils.js"></script>
-<script src="/common/dispatcher/dispatcher.js"></script>
-<script src="resources/helper.sub.js"></script>
-<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
-<script>
-promise_test(async t => {
-  // Register a service worker and make this page controlled.
-  const workerUrl =
-      'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)';
-  const registration =
-      await service_worker_unregister_and_register(t, workerUrl, './');
-  t.add_cleanup(_ => registration.unregister());
-  await wait_for_state(t, registration.installing, 'activated');
-  const controllerChanged = new Promise(
-      resolve => navigator.serviceWorker.oncontrollerchange = resolve);
-  await claim(t, registration.active);
-  await controllerChanged;
-
-  const pageA = new RemoteContext(token());
-  const pageB = new RemoteContext(token());
-
-  const urlA = location.origin + executorPath + pageA.context_id;
-  const urlB = originCrossSite + executorPath + pageB.context_id;
-
-  // Open `urlA`.
-  window.open(urlA, '_blank', 'noopener');
-  await pageA.execute_script(waitForPageShow);
-
-  // Get Clients.matchAll() and check whether `pageA` is controlled.
-  // Actual `assert_*()` is called after `assert_bfcached()` below.
-  const clients1 = await (await fetch('/get-clients-matchall')).json();
-  const controlled1 = await pageA.execute_script(
-      () => (navigator.serviceWorker.controller !== null));
-
-  // Navigate to `urlB` and get Clients.matchAll() when `urlA` is in BFCache.
-  await pageA.execute_script(
-    (url) => prepareNavigation(() => {
-      location.href = url;
-    }),
-    [urlB]);
-  await pageB.execute_script(waitForPageShow);
-  const clients2 = await (await fetch('/get-clients-matchall')).json();
-
-  // Back navigate and check whether the page is restored from BFCache.
-  await pageB.execute_script(
-    () => {
-      prepareNavigation(() => { history.back(); });
-    }
-  );
-  await pageA.execute_script(waitForPageShow);
-  await assert_bfcached(pageA);
-
-  // Get Clients.matchAll() and check whether `pageA` is controlled.
-  const clients3 = await (await fetch('/get-clients-matchall')).json();
-  const controlled3 = await pageA.execute_script(
-      () => (navigator.serviceWorker.controller !== null));
-
-  // Clients.matchAll() should not list `urlA` when it is in BFCache.
-  assert_true(clients1.indexOf(urlA) >= 0,
-      '1: matchAll() before navigation');
-  assert_true(clients2.indexOf(urlA) < 0,
-      '2: matchAll() before back navigation');
-  assert_true(clients3.indexOf(urlA) >= 0,
-      '3: matchAll() after back navigation');
-
-  // `pageA` should be controlled before/after BFCached.
-  assert_true(controlled1,
-    'pageA should be controlled before BFCached');
-  assert_true(controlled3,
-    'pageA should be controlled after restored');
-}, 'Clients.matchAll() should not list pages in BFCache');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-controlled-after-restore.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-controlled-after-restore.https.html
deleted file mode 100644
index 5a63b6e..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-controlled-after-restore.https.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!doctype html>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/utils.js"></script>
-<script src="/common/dispatcher/dispatcher.js"></script>
-<script src="resources/helper.sub.js"></script>
-<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
-<script>
-promise_test(async t => {
-  const pageA = new RemoteContext(token());
-  const pageB = new RemoteContext(token());
-
-  const urlA = location.origin + executorPath + pageA.context_id;
-  const urlB = originCrossSite + executorPath + pageB.context_id;
-
-  // Register a service worker.
-  const workerUrl =
-      'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)';
-  const registration =
-      await service_worker_unregister_and_register(t, workerUrl, './');
-  t.add_cleanup(_ => registration.unregister());
-  await wait_for_state(t, registration.installing, 'activated');
-
-  window.open(urlA, '_blank', 'noopener');
-  await pageA.execute_script(waitForPageShow);
-
-  assert_true(
-    await pageA.execute_script(
-        () => (navigator.serviceWorker.controller !== null)),
-    'pageA should be controlled before navigation');
-
-  navigateAndThenBack(pageA, pageB, urlB);
-  await assert_bfcached(pageA);
-
-  assert_true(
-    await pageA.execute_script(
-        () => (navigator.serviceWorker.controller !== null)),
-    'navigator.serviceWorker.controller should be non-null ' +
-    'after restored from BFCache');
-
-  const isControlled = await pageA.execute_script(
-      () => fetch('/is-controlled').then(r => r.text()));
-
-  assert_true(
-    await pageA.execute_script(
-        () => (navigator.serviceWorker.controller !== null)),
-    'navigator.serviceWorker.controller should be non-null ' +
-    'after restored from BFCache and after fetch');
-
-  assert_equals(isControlled, 'controlled',
-    'fetch should be intercepted after restored from BFCache');
-}, 'Pages should remain controlled after restored from BFCache');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https.html
deleted file mode 100644
index 1c3f811..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!doctype html>
-<meta name="timeout" content="long">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/utils.js"></script>
-<script src="/common/dispatcher/dispatcher.js"></script>
-<script src="resources/helper.sub.js"></script>
-<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
-<script>
-// When a service worker is unregistered when a controlled page is in BFCache,
-// the page can be still restored from BFCache and remain controlled by the
-// service worker.
-promise_test(async t => {
-  // Register a service worker and make this page controlled.
-  const workerUrl =
-      'resources/service-worker.js?pipe=header(Service-Worker-Allowed,../)';
-  const registration =
-      await service_worker_unregister_and_register(t, workerUrl, './');
-  t.add_cleanup(_ => registration.unregister());
-  await wait_for_state(t, registration.installing, 'activated');
-  const controllerChanged = new Promise(
-      resolve => navigator.serviceWorker.oncontrollerchange = resolve);
-  await claim(t, registration.active);
-  await controllerChanged;
-
-  const pageA = new RemoteContext(token());
-  const pageB = new RemoteContext(token());
-
-  const urlA = location.origin + executorPath + pageA.context_id;
-  const urlB = originCrossSite + executorPath + pageB.context_id;
-
-  // Open `urlA`.
-  window.open(urlA, '_blank', 'noopener');
-  await pageA.execute_script(waitForPageShow);
-
-  assert_true(
-    await pageA.execute_script(
-        () => (navigator.serviceWorker.controller !== null)),
-    'pageA should be controlled before navigation');
-
-  // Navigate to `urlB`.
-  await pageA.execute_script(
-    (url) => prepareNavigation(() => {
-      location.href = url;
-    }),
-    [urlB]);
-  await pageB.execute_script(waitForPageShow);
-
-  // Unregister the service worker when the controlled `pageA` is in BFCache.
-  await registration.unregister();
-
-  // Back navigate and check whether the page is restored from BFCache.
-  await pageB.execute_script(
-    () => {
-      prepareNavigation(() => { history.back(); });
-    }
-  );
-  await pageA.execute_script(waitForPageShow);
-  await assert_not_bfcached(pageA);
-
-  assert_true(
-    await pageA.execute_script(
-        () => (navigator.serviceWorker.controller === null)),
-    'pageA should not be controlled');
-
-}, 'Unregister service worker while a controlled page is in BFCache');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/disabled-click-picker-manual.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/disabled-click-picker-manual.html
new file mode 100644
index 0000000..b77f981
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/disabled-click-picker-manual.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Disabled input elements must not open pickers</title>
+<p>
+  Click the Open buttons below. If clicking them does not open any pickers, then consider this as a passing test.<br>
+  (This is manual because we don't have an event to check whether the picker is opened or not.)
+</p>
+<input disabled type="color" id="color"><button>Open</button><br>
+<input disabled type="file" id="file"><button>Open</button>
+<script>
+  for (const button of document.getElementsByTagName("button")) {
+    button.onclick = () => {
+      const input = button.previousElementSibling;
+      input.dispatchEvent(new MouseEvent("click"));
+    }
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-message-util.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-message-util.js
index 247071db..c62eb8e 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-message-util.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-message-util.js
@@ -4,6 +4,7 @@
 const messageSubject = {
   ERROR: "error",  // info field may contain more detail
   OBJECT_URL: "object url", // info field contains object URL
+  HANDLE: "handle", // info field contains the MediaSourceHandle
   STARTED_BUFFERING: "started buffering",
   FINISHED_BUFFERING: "finished buffering",
   VERIFY_DURATION: "verify duration", // info field contains expected duration
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.html
index 7b00c59..0f74d95 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.html
@@ -7,11 +7,11 @@
 <body>
 <script>
 
-const AFTER_SETTING_SRC = "after setting src";
+const AFTER_SETTING_SRCOBJECT = "after setting srcObject";
 const AFTER_STARTED_BUFFERING = "after receiving Started Buffering message from worker";
 const AFTER_FINISHED_BUFFERING = "after receiving Finished Buffering message from worker";
 
-[ AFTER_SETTING_SRC, AFTER_STARTED_BUFFERING, AFTER_FINISHED_BUFFERING ].forEach(when => {
+[ AFTER_SETTING_SRCOBJECT, AFTER_STARTED_BUFFERING, AFTER_FINISHED_BUFFERING ].forEach(when => {
   for (let timeouts = 0; timeouts < 5; ++timeouts) {
     async_test(test => { startWorkerAndDetachElement(test, when, timeouts); },
         "Test element detachment from worker MediaSource after at least " + timeouts +
@@ -22,9 +22,8 @@
 function detachElementAfterMultipleSetTimeouts(test, element, timeouts_remaining) {
   if (timeouts_remaining <= 0) {
     // While not the best way to detach, this triggers interoperable logic that
-    // includes detachment, though also begins a failed load(). We don't handle
-    // video error event, so the latter is not an issue in this test.
-    element.src='';
+    // includes detachment.
+    element.srcObject = null;
     test.step_timeout(() => { test.done(); }, 10);
   } else {
     test.step_timeout(() => {
@@ -51,11 +50,10 @@
       case messageSubject.ERROR:
         assert_unreached("Worker error: " + e.data.info);
         break;
-      case messageSubject.OBJECT_URL:
-        const url = e.data.info;
-        assert_true(url.match(/^blob:.+/) != null);
-        video.src = url;
-        if (when_to_start_timeouts == AFTER_SETTING_SRC) {
+      case messageSubject.HANDLE:
+        const handle = e.data.info;
+        video.srcObject = handle;
+        if (when_to_start_timeouts == AFTER_SETTING_SRCOBJECT) {
           detachElementAfterMultipleSetTimeouts(test, video, timeouts_to_await);
         }
         break;
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.js
index a4df32e5..10c2f84db 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-detach-element.js
@@ -14,7 +14,6 @@
 let sentStartedBufferingMessage = false;
 
 util.mediaSource.addEventListener("sourceopen", () => {
-  URL.revokeObjectURL(util.mediaSourceObjectUrl);
   let sourceBuffer;
   try {
     sourceBuffer = util.mediaSource.addSourceBuffer(util.mediaMetadata.type);
@@ -33,7 +32,7 @@
                              err => { postMessage({ subject: messageSubject.ERROR, info: err }) } );
 }, { once : true });
 
-postMessage({ subject: messageSubject.OBJECT_URL, info: util.mediaSourceObjectUrl} );
+postMessage({ subject: messageSubject.HANDLE, info: util.mediaSource.getHandle() } );
 
 // Append increasingly large pieces at a time, starting/continuing at |position|.
 // This allows buffering the test media without timeout, but also with enough
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.html
index 2cb834a5..c195775b 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.html
@@ -46,13 +46,12 @@
       case messageSubject.ERROR:
         assert_unreached("Worker error: " + e.data.info);
         break;
-      case messageSubject.OBJECT_URL:
-        const url = e.data.info;
-        assert_true(url.match(/^blob:.+/) !== null);
+      case messageSubject.HANDLE:
+        const handle = e.data.info;
         assert_equals(video.duration, NaN, "initial video duration before attachment should still be NaN");
         assert_equals(video.readyState, HTMLMediaElement.HAVE_NOTHING,
                       "initial video readyState before attachment should still be HAVE_NOTHING");
-        video.src = url;
+        video.srcObject = handle;
         break;
       case messageSubject.VERIFY_DURATION:
         assert_equals(video.duration, e.data.info, "duration should match expectation");
@@ -73,7 +72,7 @@
         // This test is a worker-driven set of verifications, and it will send
         // this message when it is complete. See comment in the worker script
         // that describes the phases of this test case.
-        assert_not_equals(video.src, "", "test should at least have set src.");
+        assert_not_equals(video.srcObject, null, "test should at least have set srcObject.");
         t.done();
         break;
       default:
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.js
index 8060594..e490134 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-duration.js
@@ -16,9 +16,9 @@
   // main thread.
   kInitial: "Initial",
 
-  // Main thread receives object URL, re-verifies that the media element
+  // Main thread receives MediaSourceHandle, re-verifies that the media element
   // duration is still NaN and readyState is still HAVE_NOTHING, and then sets
-  // the URL as the src of the media element, eventually causing worker
+  // the handle as the srcObject of the media element, eventually causing worker
   // mediaSource 'onsourceopen' event dispatch.
   kAttaching: "Awaiting sourceopen event that signals attachment is setup",
 
@@ -58,7 +58,6 @@
 
 // Setup handler for receipt of attachment completion.
 util.mediaSource.addEventListener("sourceopen", () => {
-  URL.revokeObjectURL(util.mediaSourceObjectUrl);
   assert(phase === testPhase.kAttaching, "Unexpected sourceopen received by Worker mediaSource.");
   phase = testPhase.kRequestNaNDurationCheck;
   processPhase();
@@ -181,7 +180,7 @@
     case testPhase.kInitial:
       assert(Number.isNaN(util.mediaSource.duration), "Initial unattached MediaSource duration must be NaN, but instead is " + util.mediaSource.duration);
       phase = testPhase.kAttaching;
-      postMessage({ subject: messageSubject.OBJECT_URL, info: util.mediaSourceObjectUrl });
+      postMessage({ subject: messageSubject.HANDLE, info: util.mediaSource.getHandle() });
       break;
 
     case testPhase.kAttaching:
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-get-objecturl.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-get-objecturl.js
new file mode 100644
index 0000000..e9a5af6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-get-objecturl.js
@@ -0,0 +1,13 @@
+importScripts("mediasource-worker-util.js");
+
+// Note, we do not use testharness.js utilities within the worker context
+// because it also communicates using postMessage to the main HTML document's
+// harness, and would confuse the test case message parsing there.
+
+onmessage = function(evt) {
+  postMessage({ subject: messageSubject.ERROR, info: "No message expected by Worker"});
+};
+
+let util = new MediaSourceWorkerUtil();
+
+postMessage({ subject: messageSubject.OBJECT_URL, info: URL.createObjectURL(util.mediaSource) });
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.html
new file mode 100644
index 0000000..b084fb6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<title>Test MediaSource object and handle creation, with MediaSource in dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="mediasource-message-util.js"></script>
+<script>
+
+async_test(t => {
+  // Fail fast if MSE-in-Workers is not supported.
+  assert_true(MediaSource.hasOwnProperty("canConstructInDedicatedWorker"), "MediaSource hasOwnProperty 'canConstructInDedicatedWorker'");
+  assert_true(MediaSource.canConstructInDedicatedWorker, "MediaSource.canConstructInDedicatedWorker");
+  assert_true(window.hasOwnProperty("MediaSourceHandle"), "window must have MediaSourceHandle visibility");
+
+  let worker = new Worker("mediasource-worker-play.js");
+  worker.onmessage = t.step_func(e => {
+    let subject = e.data.subject;
+    assert_true(subject != undefined, "message must have a subject field");
+    switch (subject) {
+      case messageSubject.ERROR:
+        assert_unreached("Worker error: " + e.data.info);
+        break;
+      case messageSubject.HANDLE:
+        const handle = e.data.info;
+        assert_not_equals(handle, null, "must have a non-null MediaSourceHandle");
+        assert_true(handle instanceof MediaSourceHandle, "must be a MediaSourceHandle");
+        t.done();
+        break;
+      default:
+        assert_unreached("Unexpected message subject: " + subject);
+
+    }
+  });
+}, "Test main context receipt of postMessage'd MediaSourceHandle from DedicatedWorker MediaSource");
+
+if (MediaSource.hasOwnProperty("canConstructInDedicatedWorker") && MediaSource.canConstructInDedicatedWorker === true) {
+  // If implementation claims support for MSE-in-Workers, then fetch and run
+  // some tests directly in another dedicated worker and get their results
+  // merged into those from this page.
+  fetch_tests_from_worker(new Worker("mediasource-worker-handle.js"));
+} else {
+  // Otherwise, fetch and run a test that verifies lack of support of
+  // MediaSource construction in another dedicated worker.
+  fetch_tests_from_worker(new Worker("mediasource-worker-must-fail-if-unsupported.js"));
+}
+
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.js
new file mode 100644
index 0000000..577b1fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle.js
@@ -0,0 +1,45 @@
+importScripts("/resources/testharness.js");
+
+test(t => {
+  // The Window test html conditionally fetches and runs these tests only if the
+  // implementation exposes a true-valued static canConstructInDedicatedWorker
+  // attribute on MediaSource in the Window context. So, the implementation must
+  // agree on support here in the dedicated worker context.
+
+  // Ensure we're executing in a dedicated worker context.
+  assert_true(self instanceof DedicatedWorkerGlobalScope, "self instanceof DedicatedWorkerGlobalScope");
+  assert_true(MediaSource.hasOwnProperty("canConstructInDedicatedWorker", "DedicatedWorker MediaSource hasOwnProperty 'canConstructInDedicatedWorker'"));
+  assert_true(MediaSource.canConstructInDedicatedWorker, "DedicatedWorker MediaSource.canConstructInDedicatedWorker");
+}, "MediaSource in DedicatedWorker context must have true-valued canConstructInDedicatedWorker if Window context had it");
+
+test(t => {
+  assert_true("getHandle" in MediaSource.prototype, "dedicated worker MediaSource must have getHandle");
+  assert_true(self.hasOwnProperty("MediaSourceHandle"), "dedicated worker must have MediaSourceHandle visibility");
+}, "MediaSource prototype in DedicatedWorker context must have getHandle, and worker must have MediaSourceHandle");
+
+test(t => {
+  const ms = new MediaSource();
+  assert_equals(ms.readyState, "closed");
+}, "MediaSource construction succeeds with initial closed readyState in DedicatedWorker");
+
+test(t => {
+  const ms = new MediaSource();
+  const handle = ms.getHandle();
+  assert_not_equals(handle, null, "must have a non-null getHandle result");
+  assert_true(handle instanceof MediaSourceHandle, "must be a MediaSourceHandle");
+}, "mediaSource.getHandle() in DedicatedWorker returns a MediaSourceHandle");
+
+test(t => {
+  const ms = new MediaSource();
+  const handle1 = ms.getHandle();
+  let handle2 = null;
+  assert_throws_dom("InvalidStateError", function()
+    {
+      handle2 = ms.getHandle();
+    }, "getting second handle from MediaSource instance");
+  assert_equals(handle2, null, "getting second handle from same MediaSource must have failed");
+  assert_not_equals(handle1, null, "must have a non-null result of the first getHandle");
+  assert_true(handle1 instanceof MediaSourceHandle, "first getHandle result must be a MediaSourceHandle");
+}, "mediaSource.getHandle() must not succeed more than precisely once for a MediaSource instance");
+
+done();
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.html
index 5553b5c..ae60199 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html>
-<title>Test MediaSource object and objectUrl creation and revocation, with MediaSource in dedicated worker</title>
+<title>Test MediaSource object and objectUrl creation and load via that url should fail, with MediaSource in dedicated worker</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="mediasource-message-util.js"></script>
@@ -11,7 +11,7 @@
   assert_true(MediaSource.hasOwnProperty("canConstructInDedicatedWorker"), "MediaSource hasOwnProperty 'canConstructInDedicatedWorker'");
   assert_true(MediaSource.canConstructInDedicatedWorker, "MediaSource.canConstructInDedicatedWorker");
 
-  let worker = new Worker("mediasource-worker-play.js");
+  let worker = new Worker("mediasource-worker-get-objecturl.js");
   worker.onmessage = t.step_func(e => {
     let subject = e.data.subject;
     assert_true(subject != undefined, "message must have a subject field");
@@ -21,19 +21,21 @@
         break;
       case messageSubject.OBJECT_URL:
         const url = e.data.info;
-        assert_true(url.match(/^blob:.+/) != null);
-        URL.revokeObjectURL(url);
-        // TODO(crbug.com/1196040): Revoking MediaSource objectURLs on thread
-        // that didn't create them is at best a no-op. This test case is
-        // possibly obsolete.
-        t.done();
+        const video = document.createElement("video");
+        document.body.appendChild(video);
+        video.onerror = t.step_func((target) => {
+          assert_true(video.error != null);
+          assert_equals(video.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
+          t.done();
+        });
+        video.onended = t.unreached_func("video should not have successfully loaded and played to end");
+        video.src = url;
         break;
       default:
         assert_unreached("Unexpected message subject: " + subject);
-
     }
   });
-}, "Test main context revocation of DedicatedWorker MediaSource object URL");
+}, "Test main context load of a DedicatedWorker MediaSource object URL should fail");
 
 if (MediaSource.hasOwnProperty("canConstructInDedicatedWorker") && MediaSource.canConstructInDedicatedWorker === true) {
   // If implementation claims support for MSE-in-Workers, then fetch and run
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.js
index 9a7195f..2e70d99 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-objecturl.js
@@ -20,9 +20,7 @@
 test(t => {
   const ms = new MediaSource();
   const url = URL.createObjectURL(ms);
-  assert_true(url != null);
-  assert_true(url.match(/^blob:.+/) != null);
-}, "URL.createObjectURL(mediaSource) in DedicatedWorker returns a Blob URI");
+}, "URL.createObjectURL(mediaSource) in DedicatedWorker does not throw exception");
 
 test(t => {
   const ms = new MediaSource();
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html
index ca8b6970..d6496af 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play-terminate-worker.html
@@ -40,7 +40,7 @@
     video.loop = true;
   }
 
-  if (when_to_start_timeouts == "before setting src") {
+  if (when_to_start_timeouts == "before setting srcObject") {
     terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await);
   }
 
@@ -51,11 +51,10 @@
       case messageSubject.ERROR:
         assert_unreached("Worker error: " + e.data.info);
         break;
-      case messageSubject.OBJECT_URL:
-        const url = e.data.info;
-        assert_true(url.match(/^blob:.+/) != null);
-        video.src = url;
-        if (when_to_start_timeouts == "after setting src") {
+      case messageSubject.HANDLE:
+        const handle = e.data.info;
+        video.srcObject = handle;
+        if (when_to_start_timeouts == "after setting srcObject") {
           terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await);
         }
         video.play().catch(error => {
@@ -73,7 +72,7 @@
   });
 }
 
-[ "before setting src", "after setting src", "after first ended event" ].forEach(when => {
+[ "before setting srcObject", "after setting srcObject", "after first ended event" ].forEach(when => {
   for (let timeouts = 0; timeouts < 10; ++timeouts) {
     async_test(test => { startWorkerAndTerminateWorker(test, when, timeouts); },
         "Test worker MediaSource termination after at least " + timeouts +
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.html
index 07317e6d..0292b13 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.html
@@ -26,10 +26,9 @@
       case messageSubject.ERROR:
         assert_unreached("Worker error: " + e.data.info);
         break;
-      case messageSubject.OBJECT_URL:
-        const url = e.data.info;
-        assert_true(url.match(/^blob:.+/) != null);
-        video.src = url;
+      case messageSubject.HANDLE:
+        const handle = e.data.info;
+        video.srcObject = handle;
         video.play();
         break;
       default:
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.js
index 0312f16f..e29b1b8d 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-play.js
@@ -11,7 +11,6 @@
 let util = new MediaSourceWorkerUtil();
 
 util.mediaSource.addEventListener("sourceopen", () => {
-  URL.revokeObjectURL(util.mediaSourceObjectUrl);
   sourceBuffer = util.mediaSource.addSourceBuffer(util.mediaMetadata.type);
   sourceBuffer.onerror = (err) => {
     postMessage({ subject: messageSubject.ERROR, info: err });
@@ -43,4 +42,4 @@
                              err => { postMessage({ subject: messageSubject.ERROR, info: err }) });
 }, { once : true });
 
-postMessage({ subject: messageSubject.OBJECT_URL, info: util.mediaSourceObjectUrl });
+postMessage({ subject: messageSubject.HANDLE, info: util.mediaSource.getHandle() });
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-util.js b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-util.js
index 695d1179..7adaf82 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-util.js
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-util.js
@@ -22,7 +22,6 @@
 class MediaSourceWorkerUtil {
   constructor() {
     this.mediaSource = new MediaSource();
-    this.mediaSourceObjectUrl = URL.createObjectURL(this.mediaSource);
 
     // Find supported test media, if any.
     this.foundSupportedMedia = false;
diff --git a/third_party/blink/web_tests/inspector-protocol/page/set-intercept-file-chooser-dialog.js b/third_party/blink/web_tests/inspector-protocol/page/set-intercept-file-chooser-dialog.js
index 293ac3f..ca3370b 100644
--- a/third_party/blink/web_tests/inspector-protocol/page/set-intercept-file-chooser-dialog.js
+++ b/third_party/blink/web_tests/inspector-protocol/page/set-intercept-file-chooser-dialog.js
@@ -65,6 +65,48 @@
       });
     },
 
+    async function testOpenFilePickerAPI() {
+      const [event] = await Promise.all([
+        dp.Page.onceFileChooserOpened(),
+        session.evaluateAsyncWithUserGesture(async () => {
+          try {
+            await window.showOpenFilePicker();
+          }
+          catch (e) {
+            LOG(e.message);
+          }
+        }),
+      ]);
+    },
+
+    async function testSaveFilePickerAPI() {
+      const [event] = await Promise.all([
+        dp.Page.onceFileChooserOpened(),
+        session.evaluateAsyncWithUserGesture(async () => {
+          try {
+            await window.showSaveFilePicker();
+          }
+          catch (e) {
+            LOG(e.message);
+          }
+        }),
+      ]);
+    },
+
+    async function testDirectoryPickerAPI() {
+      const [event] = await Promise.all([
+        dp.Page.onceFileChooserOpened(),
+        session.evaluateAsyncWithUserGesture(async () => {
+          try {
+            await window.showDirectoryPicker();
+          }
+          catch (e) {
+            LOG(e.message);
+          }
+        }),
+      ]);
+    },
+
     async function testErrors() {
       testRunner.log('Try enabling file interception in multiclient');
       const session2 = await page.createSession();
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https-expected.txt
deleted file mode 100644
index 4e4fb55..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Unregister service worker while a controlled page is in BFCache assert_implements: Should not be BFCached but actually was undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/inspector-protocol/page/set-intercept-file-chooser-dialog-expected.txt b/third_party/blink/web_tests/platform/generic/inspector-protocol/page/set-intercept-file-chooser-dialog-expected.txt
index 4c140236..0a9ca12e 100644
--- a/third_party/blink/web_tests/platform/generic/inspector-protocol/page/set-intercept-file-chooser-dialog-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/inspector-protocol/page/set-intercept-file-chooser-dialog-expected.txt
@@ -8,6 +8,15 @@
 file chooser mode: selectMultiple
 selected files: ["path1","path2"]
 
+Running test: testOpenFilePickerAPI
+Failed to execute 'showOpenFilePicker' on 'Window': Intercepted by Page.setInterceptFileChooserDialog().
+
+Running test: testSaveFilePickerAPI
+Failed to execute 'showSaveFilePicker' on 'Window': Intercepted by Page.setInterceptFileChooserDialog().
+
+Running test: testDirectoryPickerAPI
+Failed to execute 'showDirectoryPicker' on 'Window': Intercepted by Page.setInterceptFileChooserDialog().
+
 Running test: testErrors
 Try enabling file interception in multiclient
 {
diff --git a/third_party/blink/web_tests/platform/generic/virtual/shared-storage-fenced-frame-shadow-dom/wpt_internal/shared_storage/select-url-report-event.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/shared-storage-fenced-frame-shadow-dom/wpt_internal/shared_storage/select-url-report-event.https-expected.txt
new file mode 100644
index 0000000..0e44cafe
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/virtual/shared-storage-fenced-frame-shadow-dom/wpt_internal/shared_storage/select-url-report-event.https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = ResizeObserver loop limit exceeded
+PASS selectURL() with reportEvent()
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity-ref.html
new file mode 100644
index 0000000..a8bfb9fd
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Shared transitions: universal specificity (ref)</title>
+<link rel="help" href="https://github.com/WICG/shared-element-transitions">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<style>
+body {
+  background: pink;
+}
+div {
+  contain: paint;
+  width: 100px;
+  height: 100px;
+  background: blue;
+  border: 10px solid black;
+}
+</style>
+<div></div>
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity.html b/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity.html
new file mode 100644
index 0000000..1ccbf7d6
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/set-universal-specificity.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>Shared transitions: universal specificity</title>
+<link rel="help" href="https://github.com/WICG/shared-element-transitions">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<link rel="match" href="set-universal-specificity-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<style>
+#shared {
+  contain: paint;
+  width: 100px;
+  height: 100px;
+  background: blue;
+  page-transition-tag: shared;
+}
+
+/* We're verifying what we capture, so just display the old contents for 5 minutes.  */
+html::page-transition { background: pink; }
+html::page-transition-container(shared) { animation-duration: 300s; }
+
+html::page-transition-outgoing-image(shared) {
+  animation: unset;
+  opacity: 1;
+  border: 10px solid black;
+}
+html::page-transition-outgoing-image(*) {
+  border: 10px solid red;
+}
+
+html::page-transition-incoming-image(shared) { animation: unset; opacity: 0; }
+
+html::page-transition-outgoing-image(root) { animation: unset; opacity: 0; }
+html::page-transition-incoming-image(root) { animation: unset; opacity: 0 }
+</style>
+<div id=shared></div>
+<script>
+async function runTest() {
+  let t = document.createDocumentTransition();
+  t.start(() => {
+    requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
+  });
+}
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
index b55795c8..583f65f 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -40,7 +40,8 @@
 
   const full_url = generateURL(href, keylist);
   return await sharedStorage.selectURL(
-      "test-url-selection-operation", [full_url], {data: {'mockResult': 0}}
+      "test-url-selection-operation", [{url: full_url}],
+      {data: {'mockResult': 0}}
   );
 }
 
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/combined-setters-and-operations.https.html b/third_party/blink/web_tests/wpt_internal/shared_storage/combined-setters-and-operations.https.html
index d87574a9..00f22232 100644
--- a/third_party/blink/web_tests/wpt_internal/shared_storage/combined-setters-and-operations.https.html
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/combined-setters-and-operations.https.html
@@ -13,13 +13,20 @@
   const ancestor_key = token();
   let url0 = generateURL("resources/frame0.html", [ancestor_key]);
   let url1 = generateURL("resources/frame1.html", [ancestor_key]);
+  let url2 = generateURL("resources/frame2.html", [ancestor_key]);
 
   await sharedStorage.set('key0-set-from-document', 'value0');
   await sharedStorage.worklet.addModule("resources/verify-storage-entries-module.js");
   await sharedStorage.run("set-key0-operation");
 
   let uuid1 = await sharedStorage.selectURL(
-    "verify-storage-entries-url-selection-operation", [url0, url1]);
+      "verify-storage-entries-url-selection-operation",
+      [{url: url0,
+        reporting_metadata: {'click': "resources/frame0.html"}},
+       {url: url1,
+        reporting_metadata:
+          {'mouse interaction': "resources/frame1.html",
+          'click': "resources/frame2.html"}}]);
 
   attachFencedFrame(uuid1, 'opaque-ads');
 
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html b/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html
new file mode 100644
index 0000000..bb6c3d9
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html
@@ -0,0 +1,21 @@
+<html>
+<!DOCTYPE html>
+<script src="../../fenced_frame/resources/utils.js"></script>
+<body>
+<script>
+async function init() {
+    const [ancestor_key] = parseKeylist();
+
+    window.fence.reportEvent({
+        eventType: 'click',
+        eventData: "user clicked",
+        destination: ['shared-storage-select-url']
+    });
+
+    writeValueToServer(ancestor_key, "sender0_reported");
+}
+
+init();
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html.headers b/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html.headers
new file mode 100644
index 0000000..1b63235
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/resources/sender0.html.headers
@@ -0,0 +1 @@
+Supports-Loading-Mode: fenced-frame
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html
index 5dc945f8..eacfffc 100644
--- a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation-without-add-module.html
@@ -9,13 +9,15 @@
 promise_test(async t => {
   return promise_rejects_dom(t, "OperationError",
     sharedStorage.selectURL(
-      "test-url-selection-operation", ["resources/frame0.html"]));
+        "test-url-selection-operation", [{url: "resources/frame0.html"}]));
 }, 'selectURL() without addModule');
 
 promise_test(async t => {
-  try {
+    try {
       await sharedStorage.selectURL(
-          "test-url-selection-operation", ["1", "2", "3", "4", "5", "6", "7", "8", "9"]);
+          "test-url-selection-operation",
+          [{url: "1"}, {url: "2"}, {url: "3"}, {url: "4"}, {url: "5"},
+           {url: "6"}, {url: "7"}, {url: "8"}, {url: "9"}]);
   } catch (e) {
     assert_equals(e.name, 'DataError');
     assert_equals(e.message, 'Length of the \"urls\" parameter is not valid.');
@@ -36,5 +38,94 @@
   assert_unreached("did not reject");
 }, 'selectURL() with empty urls array');
 
+promise_test(async t => {
+  try {
+      await sharedStorage.selectURL(
+          "test-url-selection-operation", [{
+              reporting_metadata: {
+                  'click': "https://google.com"
+              }
+          }]);
+  } catch (e) {
+    assert_equals(e.name, 'TypeError');
+      assert_equals(true, e.message.startsWith(
+                    'Failed to execute \'selectURL\' on \'SharedStorage\': \
+Failed to read the \'url\' property from \'SharedStorageUrlWithMetadata\':') &&
+                    e.message.endsWith(
+'Failed to read the \'url\' property from \'SharedStorageUrlWithMetadata\': \
+Required member is undefined.'));
+    return;
+  }
+  assert_unreached("did not reject");
+}, 'selectURL() with missing url');
+
+promise_test(async t => {
+  try {
+      await sharedStorage.selectURL(
+          "test-url-selection-operation", [{
+              url: "https://#"
+          }]);
+  } catch (e) {
+    assert_equals(e.name, 'DataError');
+      assert_equals(e.message,
+                    'The url \"https://#\" is invalid.');
+    return;
+  }
+  assert_unreached("did not reject");
+}, 'selectURL() with invalid url');
+
+promise_test(async t => {
+  try {
+      await sharedStorage.selectURL(
+          "test-url-selection-operation", [{
+              url: "resources/frame0.html",
+              reporting_metadata: {
+                  'click': "https://#"
+              }
+          }]);
+  } catch (e) {
+    assert_equals(e.name, 'DataError');
+      assert_equals(e.message,
+                    'The metadata for the url at index 0 has an invalid \
+or non-HTTPS report_url parameter \"https://#\".');
+    return;
+  }
+  assert_unreached("did not reject");
+}, 'selectURL() with invalid report url');
+
+promise_test(async t => {
+  try {
+      await sharedStorage.selectURL(
+          "test-url-selection-operation", [{
+              url: "resources/frame0.html",
+              reporting_metadata: {
+                  'click': "http://google.com"
+              }
+          }]);
+  } catch (e) {
+    assert_equals(e.name, 'DataError');
+      assert_equals(e.message, 'The metadata for the url at index 0 has an \
+invalid or non-HTTPS report_url parameter \"http://google.com\".');
+    return;
+  }
+  assert_unreached("did not reject");
+}, 'selectURL() with http report url');
+
+promise_test(async t => {
+  try {
+      await sharedStorage.selectURL(
+          "test-url-selection-operation", [{
+              url: "resources/frame0.html",
+              reporting_metadata: {}
+          }]);
+  } catch (e) {
+    assert_equals(e.name, 'DataError');
+      assert_equals(e.message, 'selectURL could not get reporting_metadata \
+object attributes');
+    return;
+  }
+  assert_unreached("did not reject");
+}, 'selectURL() with invalid reporting_metadata');
+
 </script>
 </body>
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation.https.html b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation.https.html
index 8a07d568..c697545 100644
--- a/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation.https.html
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/run-url-selection-operation.https.html
@@ -17,21 +17,24 @@
   await sharedStorage.worklet.addModule("resources/simple-module.js");
 
   let uuid0 = await sharedStorage.selectURL(
-    "test-url-selection-operation", [url0, url1], {data: {'mockResult': 0}});
+      "test-url-selection-operation", [{url: url0}, {url: url1}],
+      {data: {'mockResult': 0}});
   assert_true(uuid0.startsWith('urn:uuid:'));
   attachFencedFrame(uuid0, 'opaque-ads');
   const result0 = await nextValueFromServer(ancestor_key);
   assert_equals(result0, "frame0_loaded");
 
   let uuid1 = await sharedStorage.selectURL(
-    "test-url-selection-operation", [url0, url1], {data: {'mockResult': 1}});
+      "test-url-selection-operation", [{url: url0}, {url: url1}],
+      {data: {'mockResult': 1}});
   assert_true(uuid1.startsWith('urn:uuid:'));
   attachFencedFrame(uuid1, 'opaque-ads');
   const result1 = await nextValueFromServer(ancestor_key);
   assert_equals(result1, "frame1_loaded");
 
   let uuid2 = await sharedStorage.selectURL(
-    "test-url-selection-operation", [url0, url1], {data: {'mockResult': -1}});
+      "test-url-selection-operation", [{url: url0}, {url: url1}],
+      {data: {'mockResult': -1}});
   assert_true(uuid2.startsWith('urn:uuid:'));
   attachFencedFrame(uuid2, 'opaque-ads');
   const result2 = await nextValueFromServer(ancestor_key);
diff --git a/third_party/blink/web_tests/wpt_internal/shared_storage/select-url-report-event.https.html b/third_party/blink/web_tests/wpt_internal/shared_storage/select-url-report-event.https.html
new file mode 100644
index 0000000..f7e5a1b
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/shared_storage/select-url-report-event.https.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../fenced_frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+    const ancestor_key = token();
+    let url0 = generateURL("resources/sender0.html", [ancestor_key]);
+    let url1 = generateURL("resources/sender1.html", [ancestor_key]);
+
+    await sharedStorage.worklet.addModule("resources/simple-module.js");
+
+    let uuid0 = await sharedStorage.selectURL(
+        "test-url-selection-operation", [
+            {url: url0,
+             reporting_metadata:
+                 {
+                     'click': "resources/receiver0.html",
+                     'mouse interaction': "resources/receiver1.html"
+                 }
+             }, {url: url1}
+        ], {data: {'mockResult': 0}});
+    assert_true(uuid0.startsWith('urn:uuid:'));
+    attachFencedFrame(uuid0, 'opaque-ads');
+    const result0 = await nextValueFromServer(ancestor_key);
+    assert_equals(result0, "sender0_reported");
+}, 'selectURL() with reportEvent()');
+
+</script>
+</body>
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
index b59cbe4..d7f1fac 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_1.a.sha1
@@ -1 +1 @@
-6339ab42a463c5e056531678511f76e7f02bcddc
\ No newline at end of file
+cd7b77f0e6c2beed0057fb756ff452c8da6a2d3c
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
index dc3ce90..1d9f2b20 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_Cr.a.sha1
@@ -1 +1 @@
-8915c8e8fda810cfb5a2357f4b8164a14e650db1
\ No newline at end of file
+5811a18a1913a84d1f32cb786ab11a28a223ce50
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
index 2c60cd7..d7da6e1 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_1.a.sha1
@@ -1 +1 @@
-2491547bc99c76ad9b987fe092c7699ba77ed645
\ No newline at end of file
+2c95643c59cc2edba164217583e1a86d86a2d765
\ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
index b77546e..a3292ef9 100644
--- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
+++ b/third_party/gvr-android-sdk/libgvr_shim_static_arm_Cr.a.sha1
@@ -1 +1 @@
-45a308f8f482ae4c746a84ea99d2baa50c6d9fcf
\ No newline at end of file
+68994ab909102c810edb6892b335f54db1f0b01c
\ No newline at end of file
diff --git a/third_party/maven/3pp/3pp.pb b/third_party/maven/3pp/3pp.pb
index b168ad6e..e4b0d69aa 100644
--- a/third_party/maven/3pp/3pp.pb
+++ b/third_party/maven/3pp/3pp.pb
@@ -6,8 +6,8 @@
   source {
     url {
       # See: https://maven.apache.org/download.cgi
-      download_url: "https://downloads.apache.org/maven/maven-3/3.8.5/binaries/apache-maven-3.8.5-bin.tar.gz"
-      version: "3.8.5"
+      download_url: "https://downloads.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz"
+      version: "3.8.6"
     }
     unpack_archive: true
   }
diff --git a/third_party/maven/README.chromium b/third_party/maven/README.chromium
index 184f96da..4f79f08 100644
--- a/third_party/maven/README.chromium
+++ b/third_party/maven/README.chromium
@@ -1,7 +1,7 @@
 Name: Apache Maven
 Short Name: maven
 URL: https://maven.apache.org/index.html
-Version: 3.8.5
+Version: 3.8.6
 License: Apache 2.0
 License File: NOT_SHIPPED
 Security Critical: no
diff --git a/third_party/r8/3pp/fetch.py b/third_party/r8/3pp/fetch.py
index e01ff54..8d30e7f 100755
--- a/third_party/r8/3pp/fetch.py
+++ b/third_party/r8/3pp/fetch.py
@@ -18,8 +18,15 @@
 
 
 def get_commit_before_today():
-    """Returns hash of last commit that occurred before today (by UTC)."""
-    today = datetime.datetime.now(datetime.timezone.utc).date()
+    """Returns hash of last commit that occurred before today (in Hawaii time)."""
+    # We are doing UTC-10 (Hawaii time) since midnight there is roughly equal to a
+    # time before North America starts working (where much of the chrome build
+    # team is located), and is at least partially through the workday for Denmark
+    # (where much of the R8 team is located). This ideally allows 3pp to catch
+    # R8's work faster, instead of doing UTC where we would typically have to wait
+    # ~18 hours to get R8's latest changes.
+    desired_timezone = datetime.timezone(-datetime.timedelta(hours=10))
+    today = datetime.datetime.now(desired_timezone).date()
     # Response looks like:
     # {
     # "log": [
@@ -43,12 +50,12 @@
         ctime_string = commit['committer']['time']
         commit_time = datetime.datetime.strptime(ctime_string,
                                                  "%a %b %d %H:%M:%S %Y %z")
-        utc_commit_time = commit_time.astimezone(datetime.timezone.utc)
+        normalized_commit_time = commit_time.astimezone(desired_timezone)
 
         # We are assuming that the commits are given in order of committed time.
         # This appears to be true, but I can't find anywhere that this is
         # guaranteed.
-        if utc_commit_time.date() < today:
+        if normalized_commit_time.date() < today:
             # This is the first commit we can find before today.
             return commit['commit']
 
@@ -58,15 +65,15 @@
 
 
 def compute_patch_hash():
-  this_dir = pathlib.Path(__file__).parent
-  md5 = hashlib.md5()
-  for p in sorted(this_dir.glob('patches/*.patch')):
-    md5.update(p.read_bytes())
-  # Include install.py so that it triggers changes as well.
-  md5.update((this_dir / 'install.sh').read_bytes())
-  # Shorten to avoid really long version strings. Given the low number of patch
-  # files, 10 digits is more than sufficient.
-  return md5.hexdigest()[:10]
+    this_dir = pathlib.Path(__file__).parent
+    md5 = hashlib.md5()
+    for p in sorted(this_dir.glob('patches/*.patch')):
+        md5.update(p.read_bytes())
+    # Include install.py so that it triggers changes as well.
+    md5.update((this_dir / 'install.sh').read_bytes())
+    # Shorten to avoid really long version strings. Given the low number of patch
+    # files, 10 digits is more than sufficient.
+    return md5.hexdigest()[:10]
 
 
 def do_latest():
diff --git a/third_party/turbine/3pp/3pp.pb b/third_party/turbine/3pp/3pp.pb
index 83aba71b..69104b2 100644
--- a/third_party/turbine/3pp/3pp.pb
+++ b/third_party/turbine/3pp/3pp.pb
@@ -5,6 +5,7 @@
   }
 
   build {
+    tool: "chromium/third_party/maven"
     dep: "chromium/third_party/jdk"
   }
 }
diff --git a/third_party/turbine/3pp/install.sh b/third_party/turbine/3pp/install.sh
index 43bff16..128638eb 100755
--- a/third_party/turbine/3pp/install.sh
+++ b/third_party/turbine/3pp/install.sh
@@ -10,18 +10,11 @@
 PREFIX="$1"
 DEPS_PREFIX="$2"
 
-SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
-MAVEN_VERSION="3.8.5"
-
-curl -O https://downloads.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
-tar xzf apache-maven-$MAVEN_VERSION-bin.tar.gz
-mv apache-maven-$MAVEN_VERSION $SCRIPT_DIR/
-
 # Verify mvn works
-JAVA_HOME=$DEPS_PREFIX/current PATH=$SCRIPT_DIR/apache-maven-$MAVEN_VERSION/bin:$PATH mvn -v
+JAVA_HOME=$DEPS_PREFIX/current mvn -v
 
 # Build
-JAVA_HOME=$DEPS_PREFIX/current PATH=$SCRIPT_DIR/apache-maven-$MAVEN_VERSION/bin:$PATH mvn package -DskipTests=true -q -f pom.xml
+JAVA_HOME=$DEPS_PREFIX/current mvn package -DskipTests=true -q -f pom.xml
 cp target/turbine-HEAD-SNAPSHOT-all-deps.jar turbine.jar
 
 mkdir -p $PREFIX/
diff --git a/third_party/turbine/OWNERS b/third_party/turbine/OWNERS
index a0e0826..7200601 100644
--- a/third_party/turbine/OWNERS
+++ b/third_party/turbine/OWNERS
@@ -1,2 +1,3 @@
-agrieve@chromium.org
+file://build/android/OWNERS
+
 wnwen@chromium.org
diff --git a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
index 440f1e93..69d69bf 100644
--- a/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
+++ b/third_party/zxcvbn-cpp/native-src/zxcvbn/util.cpp
@@ -43,8 +43,8 @@
 std::pair<char32_t, It> _utf8_decode(It it, It end) {
   assert(it != end);
   const char* src = &*it;
-  size_t src_len = static_cast<size_t>(std::distance(it, end));
-  size_t char_index = 0;
+  int32_t src_len = std::distance(it, end);
+  int32_t char_index = 0;
   base_icu::UChar32 code_point_out;
 
   base::ReadUnicodeCharacter(src, src_len, &char_index, &code_point_out);
diff --git a/third_party/zxcvbn-cpp/patches/base_utf8.diff b/third_party/zxcvbn-cpp/patches/base_utf8.diff
index d15bf4a8..c7a81c5b 100644
--- a/third_party/zxcvbn-cpp/patches/base_utf8.diff
+++ b/third_party/zxcvbn-cpp/patches/base_utf8.diff
@@ -56,8 +56,8 @@
 +std::pair<char32_t, It> _utf8_decode(It it, It end) {
 +  assert(it != end);
 +  const char* src = &*it;
-+  size_t src_len = static_cast<size_t>(std::distance(it, end));
-+  size_t char_index = 0;
++  int32_t src_len = std::distance(it, end);
++  int32_t char_index = 0;
 +  base_icu::UChar32 code_point_out;
  
 -bool utf8_valid(std::string::const_iterator start,
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index f239150..626187e 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -451,7 +451,7 @@
     "structures": [2800],
   },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/test/data/webui/resources.grd": {
-    "META": {"sizes": {"includes": [600],}},
+    "META": {"sizes": {"includes": [900],}},
     "includes": [2810],
   },
   "chrome/test/data/webui_test_resources.grd": {
diff --git a/tools/memory/partition_allocator/pa_tcache_inspect.cc b/tools/memory/partition_allocator/pa_tcache_inspect.cc
index 95c7887e..0a78a745 100644
--- a/tools/memory/partition_allocator/pa_tcache_inspect.cc
+++ b/tools/memory/partition_allocator/pa_tcache_inspect.cc
@@ -20,6 +20,7 @@
 #include <vector>
 
 #include "base/allocator/partition_allocator/partition_root.h"
+#include "base/allocator/partition_allocator/partition_stats.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
@@ -365,9 +366,9 @@
   std::cout << "Per thread:\n"
             << "Thread Name         Size\tPurge\n"
             << std::string(80, '-') << "\n";
-  base::ThreadCacheStats all_threads_stats = {0};
+  ThreadCacheStats all_threads_stats = {0};
   for (const auto& tcache : inspector.thread_caches()) {
-    base::ThreadCacheStats stats = {0};
+    ThreadCacheStats stats = {0};
     // No alloc stats, they reach into tcache->root_, which is not valid.
     tcache.get()->AccumulateStats(&stats);
     tcache.get()->AccumulateStats(&all_threads_stats);
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index a8eccb14..7e62e1db 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@
         },
         "win": {
             "hash": "bc2c442fac332b89ad0f9ff5c244b64fec3c2b0c",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6007fadd7cb1b558e89799b409d20529abb8c37f/trace_processor_shell.exe"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/66845965eea2742de82e11ca9467e53b01b78a31/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
@@ -14,7 +14,7 @@
         },
         "mac": {
             "hash": "37ad669f8e361ec25d649544e36abe883d11385d",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/6007fadd7cb1b558e89799b409d20529abb8c37f/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/66845965eea2742de82e11ca9467e53b01b78a31/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "9e2523358d3118333a637c080edf185cb0613e4a",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6007fadd7cb1b558e89799b409d20529abb8c37f/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/66845965eea2742de82e11ca9467e53b01b78a31/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 185138b9..3a51d2ad 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -648,10 +648,6 @@
 
 # Benchmark: wasmpspdfkit
 crbug.com/1211795 [ mac ] wasmpspdfkit/https://pspdfkit.com/webassembly-benchmark/ [ Skip ]
-crbug.com/1335392 [ linux ] wasmpspdfkit/https://pspdfkit.com/webassembly-benchmark/ [ Skip ]
-crbug.com/1335392 [ win ] wasmpspdfkit/https://pspdfkit.com/webassembly-benchmark/ [ Skip ]
-crbug.com/1335392 [ android ] wasmpspdfkit/https://pspdfkit.com/webassembly-benchmark/ [ Skip ]
-crbug.com/1335392 [ chromeos ] wasmpspdfkit/https://pspdfkit.com/webassembly-benchmark/ [ Skip ]
 
 # Benchmark: webrtc
 crbug.com/1051644 [ win ] webrtc/pause_play_peerconnections [ Skip ]
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index fdf9741..908f508 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1013,11 +1013,10 @@
     return 0;
 
   std::u16string text = obj->GetHypertext();
-  size_t text_length = text.length();
+  int32_t text_length = text.length();
 
   offset = obj->UnicodeToUTF16OffsetInText(offset);
-  offset = std::max(offset, 0);
-  size_t limited_offset = std::min(static_cast<size_t>(offset), text_length);
+  int32_t limited_offset = base::clamp(offset, 0, text_length);
 
   base_icu::UChar32 code_point;
   base::ReadUnicodeCharacter(text.c_str(), text_length + 1, &limited_offset,
@@ -4344,8 +4343,8 @@
   text_unicode_adjustments_.emplace();
 
   std::u16string text = GetHypertext();
-  size_t text_length = text.size();
-  for (size_t i = 0; i < text_length; i++) {
+  int32_t text_length = text.size();
+  for (int32_t i = 0; i < text_length; i++) {
     base_icu::UChar32 code_point;
     size_t original_i = i;
     base::ReadUnicodeCharacter(text.c_str(), text_length + 1, &i, &code_point);
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index dcc3f675..ee763bc 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -404,7 +404,6 @@
 }
 
 robolectric_library("ui_junit_test_support") {
-  testonly = true
   sources = [
     "junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java",
     "junit/src/org/chromium/ui/shadows/ShadowAppCompatResources.java",
@@ -414,7 +413,6 @@
   deps = [
     ":ui_java",
     "//base:base_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
     "//third_party/androidx:androidx_asynclayoutinflater_asynclayoutinflater_java",
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
index 00b2d470..5419b01 100644
--- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java
+++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -99,13 +99,6 @@
     }
 
     /**
-     * Cleans up clipboard on native side.
-     */
-    public static void cleanupForTesting() {
-        ClipboardJni.get().cleanupForTesting();
-    }
-
-    /**
      * Emulates the behavior of the now-deprecated
      * {@link android.text.ClipboardManager#getText()} by invoking
      * {@link android.content.ClipData.Item#coerceToText(Context)} on the first
@@ -360,6 +353,5 @@
         void onPrimaryClipTimestampInvalidated(
                 long nativeClipboardAndroid, Clipboard caller, long timestamp);
         long getLastModifiedTimeToJavaTime(long nativeClipboardAndroid);
-        void cleanupForTesting();
     }
 }
diff --git a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java
index 4da8d33..9769006 100644
--- a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java
+++ b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java
@@ -49,7 +49,7 @@
 
     @Override
     public void tearDownTest() throws Exception {
-        Clipboard.cleanupForTesting();
+        ClipboardAndroidTestSupport.cleanup();
         super.tearDownTest();
     }
 
diff --git a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTestSupport.java b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTestSupport.java
index 17ebdbe..cd45a37 100644
--- a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTestSupport.java
+++ b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTestSupport.java
@@ -13,6 +13,13 @@
 @JNINamespace("ui")
 public class ClipboardAndroidTestSupport {
     /**
+     * Cleans up clipboard on native side.
+     */
+    public static void cleanup() {
+        ClipboardAndroidTestSupportJni.get().cleanup();
+    }
+
+    /**
      * Writes HTML to the native side clipboard.
      * @param htmlText the htmlText to write.
      */
@@ -30,6 +37,7 @@
 
     @NativeMethods
     interface Natives {
+        void cleanup();
         boolean nativeWriteHtml(String htmlText);
         boolean nativeClipboardContains(String text);
     }
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc
index 26d58a8..8996b66 100644
--- a/ui/base/clipboard/clipboard_android.cc
+++ b/ui/base/clipboard/clipboard_android.cc
@@ -420,11 +420,6 @@
   return new ClipboardAndroid;
 }
 
-// Static method for testing.
-void JNI_Clipboard_CleanupForTesting(JNIEnv* env) {
-  Clipboard::DestroyClipboardForCurrentThread();
-}
-
 // ClipboardAndroid implementation.
 
 void ClipboardAndroid::OnPrimaryClipChanged(
diff --git a/ui/base/clipboard/clipboard_android_test_support.cc b/ui/base/clipboard/clipboard_android_test_support.cc
index db3cfb86..d821fdd 100644
--- a/ui/base/clipboard/clipboard_android_test_support.cc
+++ b/ui/base/clipboard/clipboard_android_test_support.cc
@@ -15,6 +15,10 @@
 
 namespace ui {
 
+void JNI_ClipboardAndroidTestSupport_Cleanup(JNIEnv* env) {
+  Clipboard::DestroyClipboardForCurrentThread();
+}
+
 jboolean JNI_ClipboardAndroidTestSupport_NativeWriteHtml(
     JNIEnv* env,
     const base::android::JavaParamRef<jstring>& j_html_text) {
diff --git a/ui/events/keycodes/dom/keycode_converter.cc b/ui/events/keycodes/dom/keycode_converter.cc
index f5d61aa..d0f8c2a 100644
--- a/ui/events/keycodes/dom/keycode_converter.cc
+++ b/ui/events/keycodes/dom/keycode_converter.cc
@@ -336,8 +336,8 @@
   }
   // Otherwise, if the string contains a single Unicode character,
   // the key value is that character.
-  const size_t key_length = key.length();
-  size_t char_index = 0;
+  const auto key_length = static_cast<int32_t>(key.length());
+  int32_t char_index = 0;
   base_icu::UChar32 character;
   if (base::ReadUnicodeCharacter(key.data(), key_length, &char_index,
                                  &character) &&
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index 944dd4e8..3fa34577 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -213,16 +213,7 @@
       "//ui/file_manager/file_manager/foreground/js:build_worker",
     ]
   } else {
-    manifest_files = [
-      "$target_gen_dir/manifest_preprocess_generated_image_loader.json",
-      "$target_gen_dir/manifest_preprocess_static_image_loader.json",
-      "$target_gen_dir/tsconfig.manifest",
-    ]
-
-    deps += [
-      ":preprocess_generated_image_loader",
-      ":preprocess_static_image_loader",
-    ]
+    manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
   }
 }
 
@@ -258,10 +249,44 @@
   extra_deps = [
     ":copy_ts",
     ":preprocess_generated",
+    ":preprocess_generated_image_loader",
     ":preprocess_static",
+    ":preprocess_static_image_loader",
   ]
 
   deps = [ "//ui/webui/resources:library" ]
 
-  in_files = static_js_files + generated_js_files + ts_files
+  in_files = static_js_files + generated_js_files + ts_files +
+             image_loader_static_js_files + image_loader_generated_js_files
+
+  definitions = [
+    "//ui/file_manager/file_manager/definitions/file_manager.d.ts",
+    "//ui/file_manager/file_manager/definitions/volume_manager.d.ts",
+  ]
+}
+
+# GRD for test files.
+generate_grd("build_tests_grdp") {
+  testonly = true
+  grd_prefix = "file_manager_test"
+  out_grd = "$target_gen_dir/tests_resources.grdp"
+
+  input_files_base_dir = rebase_path(".", "//")
+  input_files = unittest_files
+  deps = [ ":unit_test_data" ]
+}
+
+# GRD for the actual application files that are processed by TS compiler.
+generate_grd("build_tests_gen_grdp") {
+  testonly = true
+  grd_prefix = "file_manager_test"
+  out_grd = "$target_gen_dir/tests_gen_resources.grdp"
+
+  input_files_base_dir = rebase_path(target_gen_dir, root_build_dir)
+  input_files = generated_test_htmls
+  manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
+  deps = [
+    ":build_ts",
+    ":unit_test_data",
+  ]
 }
diff --git a/ui/file_manager/base/gn/js_test_gen_html.py b/ui/file_manager/base/gn/js_test_gen_html.py
index 761a57be..0454e2d0 100644
--- a/ui/file_manager/base/gn/js_test_gen_html.py
+++ b/ui/file_manager/base/gn/js_test_gen_html.py
@@ -24,53 +24,55 @@
 
 
 def _process_js_module(input_file, output_filename):
-  """Generates the HTML for a unittest based on JS Modules.
+    """Generates the HTML for a unittest based on JS Modules.
 
   Args:
     input_file: The path for the unittest JS module.
     output_filename: The path/filename for HTML to be generated.
   """
 
-  # Map //ui/file_manager files to test URL:
-  js_module_url = input_file.replace(
-      'ui/file_manager/', 'chrome://file_manager_test/ui/file_manager/', 1)
+    # Map //ui/file_manager files to test URL:
+    js_module_url = input_file.replace('ui/file_manager/',
+                                       'chrome://webui-test/', 1)
 
-  with open(output_filename, 'w') as out:
-    out.write(_HTML_FILE_START + '\n')
+    with open(output_filename, 'w') as out:
+        out.write(_HTML_FILE_START + '\n')
 
-    line = _JS_MODULE % (js_module_url)
-    out.write(line + '\n')
+        line = _JS_MODULE % (js_module_url)
+        out.write(line + '\n')
 
-    line = _JS_MODULE_REGISTER_TESTS % (js_module_url)
-    out.write(line + '\n')
+        line = _JS_MODULE_REGISTER_TESTS % (js_module_url)
+        out.write(line + '\n')
 
 
 def main():
-  parser = ArgumentParser()
-  parser.add_argument(
-      '-s', '--src_path', help='Path to //src/ directory', required=True)
-  parser.add_argument(
-      '-i',
-      '--input',
-      help='Input dependency file generated by js_library.py',
-      required=True)
-  parser.add_argument(
-      '-o',
-      '--output',
-      help='Generated html output with flattened dependencies',
-      required=True)
-  parser.add_argument('-t', '--target_name', help='Test target name')
-  args = parser.parse_args()
+    parser = ArgumentParser()
+    parser.add_argument('-s',
+                        '--src_path',
+                        help='Path to //src/ directory',
+                        required=True)
+    parser.add_argument(
+        '-i',
+        '--input',
+        help='Input dependency file generated by js_library.py',
+        required=True)
+    parser.add_argument(
+        '-o',
+        '--output',
+        help='Generated html output with flattened dependencies',
+        required=True)
+    parser.add_argument('-t', '--target_name', help='Test target name')
+    args = parser.parse_args()
 
-  # Convert from:
-  # gen/ui/file_manager/file_manager/common/js/example_unittest.m.js_library
-  # To:
-  # ui/file_manager/file_manager/common/js/example_unittest.m.js
-  path_test_file = args.input.replace('gen/', '', 1)
-  path_test_file = path_test_file.replace('.js_library', '.js')
-  _process_js_module(path_test_file, args.output)
-  return
+    # Convert from:
+    # gen/ui/file_manager/file_manager/common/js/example_unittest.m.js_library
+    # To:
+    # ui/file_manager/file_manager/common/js/example_unittest.m.js
+    path_test_file = args.input.replace('gen/', '', 1)
+    path_test_file = path_test_file.replace('.js_library', '.js')
+    _process_js_module(path_test_file, args.output)
+    return
 
 
 if __name__ == '__main__':
-  main()
+    main()
diff --git a/ui/file_manager/file_manager/definitions/file_manager.d.ts b/ui/file_manager/file_manager/definitions/file_manager.d.ts
new file mode 100644
index 0000000..8d7f6df1
--- /dev/null
+++ b/ui/file_manager/file_manager/definitions/file_manager.d.ts
@@ -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.
+
+/// <reference types="./volume_manager" />
+
+/**
+ * Type definition for foreground/js/file_manager.js:FileManager.
+ *
+ * For now only defining the bare minimum.
+ */
+interface FileManager {
+  volumeManager: VolumeManager;
+}
+
+/**
+ * The singleton instance for FileManager is available in the Window object.
+ */
+declare global {
+  interface Window {
+    fileManager: FileManager;
+  }
+}
+
+export {};
diff --git a/ui/file_manager/file_manager/definitions/volume_manager.d.ts b/ui/file_manager/file_manager/definitions/volume_manager.d.ts
new file mode 100644
index 0000000..928f334
--- /dev/null
+++ b/ui/file_manager/file_manager/definitions/volume_manager.d.ts
@@ -0,0 +1,10 @@
+// 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.
+
+/**
+ * Type definition for file_manager/externs/volume_manager.js:VolumeManager.
+ *
+ * For now only defining the bare minimum.
+ */
+interface VolumeManager {}
diff --git a/ui/file_manager/file_manager/externs/ts/store.js b/ui/file_manager/file_manager/externs/ts/store.js
new file mode 100644
index 0000000..a4dfa22
--- /dev/null
+++ b/ui/file_manager/file_manager/externs/ts/store.js
@@ -0,0 +1,34 @@
+// 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.
+
+/**
+ * @fileoverview Simplified interfaces of the Store used by Files app. Used to
+ * be able to type check the JS files using Closure compiler.
+ * See lib/base_store.ts and state/store.ts for the implementation.
+ */
+
+/** @record */
+class Store {
+  /** @param {!Object} action */
+  dispatch(action) {}
+
+  /**
+   *  @param {!StoreObserver} observer
+   *  @returns {function()} the function to unsubscribe.
+   */
+  subscribe(observer) {}
+
+  /** @param {!StoreObserver} observer */
+  usubscribe(observer) {}
+}
+
+/**
+ * Interface marked as `record` so it doesn't have to mark implements
+ * explicitly.
+ * @record
+ */
+class StoreObserver {
+  /** @param {!Object} newState */
+  onStateChanged(newState) {}
+}
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 2fb16b9..3f52f49 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -444,6 +444,8 @@
     "//ui/webui/resources/js/cr/ui:list_selection_model.m",
     "//ui/webui/resources/js/cr/ui:list_single_selection_model.m",
   ]
+
+  externs_list = [ "//ui/file_manager/file_manager/externs/ts/store.js" ]
 }
 
 js_unittest("directory_model_unittest.m") {
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 a23fda5..71543c64 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -18,6 +18,8 @@
 import {FakeEntry, FilesAppDirEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
 import {VolumeInfo} from '../../externs/volume_info.js';
 import {VolumeManager} from '../../externs/volume_manager.js';
+import {changeDirectory} from '../../state/actions.js';
+import {getStore} from '../../state/store.js';
 
 import {constants} from './constants.js';
 import {ContentScanner, CrostiniMounter, DirectoryContents, DirectoryContentScanner, DriveMetadataSearchContentScanner, DriveSearchContentScanner, FileFilter, FileListContext, GuestOsMounter, LocalSearchContentScanner, MediaViewContentScanner, RecentContentScanner} from './directory_contents.js';
@@ -129,6 +131,9 @@
 
     /** @private {FilesAppDirEntry} */
     this.myFilesEntry_ = null;
+
+    /** @private {!Store} */
+    this.store_ = getStore();
   }
 
   /**
@@ -1174,6 +1179,9 @@
       event.newDirEntry = dirEntry;
       event.volumeChanged = previousVolumeInfo !== currentVolumeInfo;
       this.dispatchEvent(event);
+      if (util.isFilesAppExperimental()) {
+        this.store_.dispatch(changeDirectory({to: dirEntry}));
+      }
     });
   }
 
diff --git a/ui/file_manager/file_manager/lib/base_store.ts b/ui/file_manager/file_manager/lib/base_store.ts
index fe700a2..16ca217 100644
--- a/ui/file_manager/file_manager/lib/base_store.ts
+++ b/ui/file_manager/file_manager/lib/base_store.ts
@@ -87,7 +87,7 @@
   /**
    * Subscribe to Store changes/updates.
    * @param observer Callback called whenever the Store is updated.
-   * @returns callback to unsusbscribe the obserer.
+   * @returns callback to unsusbscribe the observer.
    */
   subscribe(observer: StoreObserver<StateType>):
       (observer: StoreObserver<StateType>) => void {
@@ -154,7 +154,7 @@
   }
 
   /** Synchronously call apply the `action` by calling the reducer.  */
-  dispatchInternal_(action: ActionType) {
+  private dispatchInternal_(action: ActionType) {
     // action(this.reduce.bind(this));
     this.reduce(action);
   }
diff --git a/ui/file_manager/file_manager/state/actions.ts b/ui/file_manager/file_manager/state/actions.ts
new file mode 100644
index 0000000..2cf33a5
--- /dev/null
+++ b/ui/file_manager/file_manager/state/actions.ts
@@ -0,0 +1,36 @@
+// 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 {BaseAction} from '../lib/base_store.js';
+
+import {FileKey} from './file_key.js';
+
+/**
+ * Base class for all Actions in Files app.
+ *
+ * It enforces the type/enum for the `type` attribute.
+ */
+export interface Action extends BaseAction {
+  type: Actions;
+}
+
+/** Enum to identify every Action in Files app. */
+export const enum Actions {
+  CHANGE_DIRECTORY = 'change-directory',
+}
+
+/** Action to request to change the Current Directory. */
+export interface ChangeDirectoryAction extends Action {
+  newDirectory: Entry;
+  key: FileKey;
+}
+
+/** Factory for the ChangeDirectoryAction. */
+export function changeDirectory({to}: {to: Entry}): ChangeDirectoryAction {
+  return {
+    type: Actions.CHANGE_DIRECTORY,
+    newDirectory: to,
+    key: to.toURL(),
+  };
+}
diff --git a/ui/file_manager/file_manager/state/file_key.ts b/ui/file_manager/file_manager/state/file_key.ts
new file mode 100644
index 0000000..280da3ac
--- /dev/null
+++ b/ui/file_manager/file_manager/state/file_key.ts
@@ -0,0 +1,10 @@
+// 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.
+
+/**
+ * Key to identify a file/entry.
+ *
+ * Type to distinguish it from a regular string.
+ */
+export type FileKey = string;
diff --git a/ui/file_manager/file_manager/state/reducers.ts b/ui/file_manager/file_manager/state/reducers.ts
index 0ed20d6..94d70063 100644
--- a/ui/file_manager/file_manager/state/reducers.ts
+++ b/ui/file_manager/file_manager/state/reducers.ts
@@ -2,16 +2,77 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {BaseAction} from '../lib/base_store.js';
+import {PathComponent} from '../foreground/js/path_component.js';
 
-import {State} from './state.js';
+import {Action, Actions, ChangeDirectoryAction} from './actions.js';
+import {CurrentDirectory, State} from './state.js';
 
-/** TODO(lucmult): Document this. */
-export function rootReducer(currentState: State, action: BaseAction): State {
-  if (action.type) {
-    return Object.assign(currentState, {});
+/**
+ * Root reducer for Files app.
+ * It dispatches to other reducers to update different parts of the State.
+ */
+export function rootReducer(currentState: State, action: Action): State {
+  // Before any actual Reducer, we cache the entries, so the reducers can just
+  // use any entry from `allEntries`.
+  const state = cacheEntries(currentState, action);
+
+  switch (action.type) {
+    case Actions.CHANGE_DIRECTORY:
+      return Object.assign(state, {
+        currentDirectory:
+            changeDirectory(state, action as ChangeDirectoryAction)
+      });
+
+    default:
+      console.error(`invalid action: ${action.type}`);
+      return state;
+  }
+}
+
+/** Caches the Action's entry in the `allEntries` attribute. */
+export function cacheEntries(currentState: State, action: Action): State {
+  if (action.type === Actions.CHANGE_DIRECTORY) {
+    const {newDirectory, key} = (action as ChangeDirectoryAction);
+
+    const allEntries = currentState.allEntries || {};
+    const entryData = allEntries[key] || {};
+    allEntries[key] = Object.assign(entryData, {
+      entry: newDirectory,
+    });
+
+    currentState.allEntries = allEntries;
   }
 
-  console.error('invalid action');
   return currentState;
 }
+
+/** Reducer that updates the `currentDirectory` attributes. */
+export function changeDirectory(
+    currentState: State, action: ChangeDirectoryAction): CurrentDirectory|null {
+  const fileData = currentState.allEntries[action.key];
+  if (!fileData) {
+    console.debug(`Can't find the entry with ${action.key}`);
+    return currentState.currentDirectory || null;
+  }
+
+  // TODO(lucmult): Find a correct way to grab the VolumeManager.
+  const volumeManager = window.fileManager.volumeManager;
+  if (!volumeManager) {
+    console.debug(`VolumeManager not available yet.`);
+    return currentState.currentDirectory || null;
+  }
+
+  const components =
+      PathComponent.computeComponentsFromEntry(fileData.entry, volumeManager);
+
+  return Object.assign(currentState.currentDirectory || {}, {
+    key: (action as ChangeDirectoryAction).key,
+    pathComponents: components.map(c => {
+      return {
+        name: c.name,
+        label: c.name,
+        key: c.url_,
+      };
+    })
+  });
+}
diff --git a/ui/file_manager/file_manager/state/state.ts b/ui/file_manager/file_manager/state/state.ts
index 7b60eed..21596cf 100644
--- a/ui/file_manager/file_manager/state/state.ts
+++ b/ui/file_manager/file_manager/state/state.ts
@@ -2,5 +2,49 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/** TODO(lucmult): Document this. */
-export interface State {}
+import {FilesAppDirEntry, FilesAppEntry} from '../externs/files_app_entry_interfaces.js';
+
+import {FileKey} from './file_key.js';
+
+export type AnyEntry = Entry|FilesAppEntry;
+export type OnlyDirEntry = DirectoryEntry|FilesAppDirEntry;
+
+/** The data for each individual file/entry. */
+export interface FileData {
+  entry: AnyEntry;
+}
+
+/**
+ * Describes each part of the path, as in each parent folder and/or root volume.
+ */
+export interface PathComponent {
+  // The actual name for folder/volume.
+  name: string;
+
+  // Label to display to the user, it might differ from the name when the folder
+  // or volume has a translation or comercial name.
+  label: string;
+
+  // The key to the actual folder or root, it might be a key for a fake entry.
+  key: FileKey;
+}
+
+/** The Current Directory. */
+export interface CurrentDirectory {
+  // Key to the current directory.
+  key: FileKey;
+
+  // Elements for the user facing path, e.g. the breadcrumbs.
+  pathComponents: PathComponent[];
+}
+
+/** Files app's state. */
+export interface State {
+  // A big bucket with all entries managed by the app.
+  allEntries: {
+    [key: FileKey]: FileData,
+  };
+
+  // The currently selected directory.
+  currentDirectory?: CurrentDirectory;
+}
diff --git a/ui/file_manager/file_manager/state/store.ts b/ui/file_manager/file_manager/state/store.ts
index 769e428..ad017739 100644
--- a/ui/file_manager/file_manager/state/store.ts
+++ b/ui/file_manager/file_manager/state/store.ts
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {BaseAction, BaseStore} from '../lib/base_store.js';
+import {BaseStore} from '../lib/base_store.js';
 
+import {Action} from './actions.js';
 import {rootReducer} from './reducers.js';
 import {State} from './state.js';
 
@@ -12,7 +13,7 @@
  *
  * It enforces the types for the State and the Actions managed by Files app.
  */
-export type Store = BaseStore<State, BaseAction>;
+export type Store = BaseStore<State, Action>;
 
 /**
  * Store singleton instance.
@@ -28,7 +29,7 @@
  */
 export function getStore(): Store {
   if (!store) {
-    store = new BaseStore<State, BaseAction>({}, rootReducer);
+    store = new BaseStore<State, Action>({allEntries: {}}, rootReducer);
   }
 
   return store;
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index b4e76ef..c5867c18 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -42,7 +42,10 @@
   "file_manager/background/js/media_scanner.js",
   "file_manager/background/js/metadata_proxy.js",
   "file_manager/background/js/metrics_start.js",
+
+  # TODO(lucmult): Check if we can move those mocks to the test files section.
   "file_manager/background/js/mock_crostini.js",
+  "file_manager/background/js/mock_drive_sync_handler.js",
   "file_manager/background/js/mock_file_operation_manager.js",
   "file_manager/background/js/mock_media_scanner.js",
   "file_manager/background/js/mock_progress_center.js",
@@ -83,6 +86,7 @@
   "file_manager/common/js/notifications_browser_proxy.js",
   "file_manager/common/js/power.js",
   "file_manager/common/js/progress_center_common.js",
+  "file_manager/common/js/recent_date_bucket.js",
   "file_manager/common/js/storage_adapter.js",
   "file_manager/common/js/test_error_reporting.js",
   "file_manager/common/js/test_importer_common.js",
@@ -261,6 +265,8 @@
   "file_manager/state/store.ts",
   "file_manager/state/state.ts",
   "file_manager/state/reducers.ts",
+  "file_manager/state/actions.ts",
+  "file_manager/state/file_key.ts",
 ]
 
 # Generated files are built from the repository and the final JS files is only
@@ -314,4 +320,90 @@
   "file_manager/foreground/js/ui/banners/warning_banner.js",
   "file_manager/foreground/js/ui/breadcrumb.js",
 ]
+
 # END: generated_js_files.
+
+# Test files:
+unittest_files = [
+  "file_manager/common/js/util_unittest.m.js",
+  "file_manager/common/js/filtered_volume_manager_unittest.m.js",
+  "file_manager/common/js/file_type_unittest.m.js",
+  "file_manager/common/js/lru_cache_unittest.m.js",
+  "file_manager/common/js/importer_common_unittest.m.js",
+  "file_manager/common/js/files_app_entry_types_unittest.m.js",
+  "file_manager/common/js/recent_date_bucket_unittest.m.js",
+  "file_manager/common/js/storage_adapter_unittest.m.js",
+  "file_manager/common/js/volume_manager_types_unittest.m.js",
+  "file_manager/background/js/mount_metrics_unittest.m.js",
+  "file_manager/background/js/drive_sync_handler_unittest.m.js",
+  "file_manager/background/js/media_import_handler_unittest.m.js",
+  "file_manager/background/js/task_queue_unittest.m.js",
+  "file_manager/background/js/file_operation_handler_unittest.m.js",
+  "file_manager/background/js/file_operation_manager_unittest.m.js",
+  "file_manager/background/js/trash_unittest.m.js",
+  "file_manager/background/js/duplicate_finder_unittest.m.js",
+  "file_manager/background/js/volume_manager_unittest.m.js",
+  "file_manager/background/js/media_scanner_unittest.m.js",
+  "file_manager/background/js/import_history_unittest.m.js",
+  "file_manager/background/js/metadata_proxy_unittest.m.js",
+  "file_manager/background/js/crostini_unittest.m.js",
+  "file_manager/background/js/device_handler_unittest.m.js",
+  "file_manager/foreground/elements/files_password_dialog_unittest.m.js",
+  "file_manager/foreground/elements/files_xf_elements_unittest.m.js",
+  "file_manager/foreground/elements/files_toast_unittest.m.js",
+  "file_manager/foreground/elements/files_tooltip_unittest.m.js",
+  "file_manager/foreground/js/metadata/image_orientation_unittest.m.js",
+  "file_manager/foreground/js/metadata/metadata_cache_item_unittest.m.js",
+  "file_manager/foreground/js/metadata/exif_parser_unittest.m.js",
+  "file_manager/foreground/js/metadata/thumbnail_model_unittest.m.js",
+  "file_manager/foreground/js/metadata/metadata_model_unittest.m.js",
+  "file_manager/foreground/js/metadata/content_metadata_provider_unittest.m.js",
+  "file_manager/foreground/js/metadata/external_metadata_provider_unittest.m.js",
+  "file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.m.js",
+  "file_manager/foreground/js/metadata/metadata_cache_set_unittest.m.js",
+  "file_manager/foreground/js/metadata/multi_metadata_provider_unittest.m.js",
+  "file_manager/foreground/js/file_manager_commands_unittest.m.js",
+  "file_manager/foreground/js/task_controller_unittest.m.js",
+  "file_manager/foreground/js/thumbnail_loader_unittest.m.js",
+  "file_manager/foreground/js/directory_contents_unittest.m.js",
+  "file_manager/foreground/js/file_list_model_unittest.m.js",
+  "file_manager/foreground/js/banner_controller_unittest.m.js",
+  "file_manager/foreground/js/providers_model_unittest.m.js",
+  "file_manager/foreground/js/spinner_controller_unittest.m.js",
+  "file_manager/foreground/js/banner_util_unittest.m.js",
+  "file_manager/foreground/js/list_thumbnail_loader_unittest.m.js",
+  "file_manager/foreground/js/file_type_filters_controller_unittest.m.js",
+  "file_manager/foreground/js/path_component_unittest.m.js",
+  "file_manager/foreground/js/actions_model_unittest.m.js",
+  "file_manager/foreground/js/ui/file_manager_dialog_base_unittest.m.js",
+  "file_manager/foreground/js/ui/actions_submenu_unittest.m.js",
+  "file_manager/foreground/js/ui/file_table_unittest.m.js",
+  "file_manager/foreground/js/ui/file_tap_handler_unittest.m.js",
+  "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.m.js",
+  "file_manager/foreground/js/ui/file_table_list_unittest.m.js",
+  "file_manager/foreground/js/ui/multi_menu_unittest.m.js",
+  "file_manager/foreground/js/ui/banners/state_banner_unittest.m.js",
+  "file_manager/foreground/js/ui/banners/educational_banner_unittest.m.js",
+  "file_manager/foreground/js/ui/banners/warning_banner_unittest.m.js",
+  "file_manager/foreground/js/ui/breadcrumb_unittest.m.js",
+  "file_manager/foreground/js/ui/file_list_selection_model_unittest.m.js",
+  "file_manager/foreground/js/ui/directory_tree_unittest.m.js",
+  "file_manager/foreground/js/navigation_list_model_unittest.m.js",
+  "file_manager/foreground/js/directory_model_unittest.m.js",
+  "file_manager/foreground/js/file_tasks_unittest.m.js",
+  "file_manager/foreground/js/file_transfer_controller_unittest.m.js",
+  "file_manager/foreground/js/import_controller_unittest.m.js",
+  "image_loader/scheduler_unittest.m.js",
+  "image_loader/image_loader_unittest.m.js",
+  "image_loader/cache_unittest.m.js",
+  "image_loader/image_loader_client_unittest.m.js",
+]
+
+generated_test_htmls = []
+foreach(_t, unittest_files) {
+  generated_test_htmls += [ string_replace(_t, ".js", "_gen.html") ]
+}
+
+# Files that don't have the generated HTML, but are used for tests.
+unittest_files += [ "file_manager/common/js/mock_util.js" ]
+# END: Test files.
diff --git a/ui/file_manager/tsconfig_base.json b/ui/file_manager/tsconfig_base.json
index 9844915..0082576 100644
--- a/ui/file_manager/tsconfig_base.json
+++ b/ui/file_manager/tsconfig_base.json
@@ -7,7 +7,9 @@
       "../../third_party/node/node_modules/@types"
     ],
     "types": [
-      "trusted-types"
+      "trusted-types",
+      "filesystem",
+      "filewriter"
     ]
   }
 }
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 1f69abd..117fa6fc 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -748,11 +748,6 @@
 
   SkColor tab_border = GetBorderColor("GtkButton#button");
   // Separates the toolbar from the bookmark bar or butter bars.
-  colors_[ThemeProperties::COLOR_DOWNLOAD_SHELF_CONTENT_AREA_SEPARATOR] =
-      tab_border;
-  colors_[ThemeProperties::COLOR_INFOBAR_CONTENT_AREA_SEPARATOR] = tab_border;
-  colors_[ThemeProperties::COLOR_SIDE_PANEL_CONTENT_AREA_SEPARATOR] =
-      tab_border;
   colors_[ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR] = tab_border;
   // Separates entries in the downloads bar.
   colors_[ThemeProperties::COLOR_TOOLBAR_VERTICAL_SEPARATOR] = tab_border;
@@ -809,8 +804,6 @@
         color_utils::GetResultingPaintColor(GetBgColor(""), frame_color);
 
     color_map[ThemeProperties::COLOR_TOOLBAR] = tab_color;
-    color_map[ThemeProperties::COLOR_DOWNLOAD_SHELF] = tab_color;
-    color_map[ThemeProperties::COLOR_INFOBAR] = tab_color;
     color_map[ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE] =
         tab_color;
     color_map[ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE] =
@@ -832,11 +825,6 @@
                   COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO] =
         background_tab_text_color_inactive;
 
-    color_map[ThemeProperties::COLOR_OMNIBOX_TEXT] =
-        color_provider->GetColor(ui::kColorTextfieldForeground);
-    color_map[ThemeProperties::COLOR_OMNIBOX_BACKGROUND] =
-        color_provider->GetColor(ui::kColorTextfieldBackground);
-
     // These colors represent the border drawn around tabs and between
     // the tabstrip and toolbar.
     SkColor toolbar_top_separator = GetBorderColor(
diff --git a/ui/views/test/widget_test.cc b/ui/views/test/widget_test.cc
index b1dd4a9..12a46573 100644
--- a/ui/views/test/widget_test.cc
+++ b/ui/views/test/widget_test.cc
@@ -12,6 +12,11 @@
 #include "ui/views/test/native_widget_factory.h"
 #include "ui/views/widget/root_view.h"
 
+#if BUILDFLAG(IS_MAC)
+#include "base/test/scoped_run_loop_timeout.h"
+#include "base/test/test_timeouts.h"
+#endif
+
 #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && \
     !BUILDFLAG(IS_CHROMECAST)
 #include "ui/views/test/test_desktop_screen_ozone.h"
@@ -223,8 +228,15 @@
 WidgetActivationWaiter::~WidgetActivationWaiter() = default;
 
 void WidgetActivationWaiter::Wait() {
-  if (!observed_)
+  if (!observed_) {
+#if BUILDFLAG(IS_MAC)
+    // Some tests waiting on widget creation + activation are flaky due to
+    // timeout. crbug.com/1327590.
+    const base::test::ScopedRunLoopTimeout increased_run_timeout(
+        FROM_HERE, TestTimeouts::action_max_timeout());
+#endif
     run_loop_.Run();
+  }
 }
 
 void WidgetActivationWaiter::OnWidgetActivationChanged(Widget* widget,
diff --git a/ui/webui/resources/cr_components/app_management/more_permissions_item.ts b/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
index 3210571..b427073 100644
--- a/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
+++ b/ui/webui/resources/cr_components/app_management/more_permissions_item.ts
@@ -37,7 +37,7 @@
     this.addEventListener('click', this.onClick_);
   }
 
-  onClick_() {
+  private onClick_() {
     BrowserProxy.getInstance().handler.openNativeSettings(this.app.id);
     recordAppManagementUserAction(
         this.app.type, AppManagementUserAction.NATIVE_SETTINGS_OPENED);
diff --git a/ui/webui/resources/cr_components/app_management/uninstall_button.ts b/ui/webui/resources/cr_components/app_management/uninstall_button.ts
index 95af842..377d58cc 100644
--- a/ui/webui/resources/cr_components/app_management/uninstall_button.ts
+++ b/ui/webui/resources/cr_components/app_management/uninstall_button.ts
@@ -39,7 +39,7 @@
   /**
    * Returns true if the button should be disabled due to app install type.
    */
-  getDisableState_(app: App): boolean {
+  private getDisableState_(app: App): boolean {
     if (!app) {
       return true;
     }
diff --git a/ui/webui/resources/cr_components/app_management/window_mode_item.ts b/ui/webui/resources/cr_components/app_management/window_mode_item.ts
index 12736123..92197a7 100644
--- a/ui/webui/resources/cr_components/app_management/window_mode_item.ts
+++ b/ui/webui/resources/cr_components/app_management/window_mode_item.ts
@@ -57,7 +57,7 @@
         .querySelector<AppManagementToggleRowElement>('#toggle-row')!.click();
   }
 
-  toggleWindowMode_() {
+  private toggleWindowMode_() {
     assert(this.app);
     const currentWindowMode = this.app.windowMode;
     if (currentWindowMode === WindowMode.kUnknown) {
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.ts b/ui/webui/resources/cr_elements/cr_slider/cr_slider.ts
index 7be4089..d3473612 100644
--- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.ts
+++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.ts
@@ -461,6 +461,8 @@
     }
   }
 
+  // Overridden from PaperRippleBehavior
+  /* eslint-disable-next-line @typescript-eslint/naming-convention */
   override _createRipple() {
     this._rippleContainer = this.$.knob;
     const ripple = super._createRipple();
diff --git a/ui/webui/resources/js/cr/ui/list.m.d.ts b/ui/webui/resources/js/cr/ui/list.m.d.ts
index 4d574846..643b0cd4 100644
--- a/ui/webui/resources/js/cr/ui/list.m.d.ts
+++ b/ui/webui/resources/js/cr/ui/list.m.d.ts
@@ -38,8 +38,6 @@
   startBatchUpdates(): void;
   endBatchUpdates(): void;
   decorate(): void;
-  measureItemHeight_(item: ListItem): number;
-  getItemHeightByIndex_(index: number): number;
   measureItem(item?: ListItem): Size|undefined;
   getListItemAncestor(element?: HTMLElement): HTMLElement|undefined;
   handleKeyDown(e: Event): void;
diff --git a/url/BUILD.gn b/url/BUILD.gn
index 0a488519..7997d4d 100644
--- a/url/BUILD.gn
+++ b/url/BUILD.gn
@@ -310,12 +310,10 @@
   # Unlike gurl_junit_test_support targets depending on gurl_junit_shadows must
   # bypass platform checks.
   robolectric_library("gurl_junit_shadows") {
-    testonly = true
     sources = [ "android/test/java/src/org/chromium/url/ShadowGURL.java" ]
     deps = [
       ":gurl_java",
       ":gurl_junit_test_support",
-      "//third_party/android_deps:robolectric_all_java",
     ]
   }
 
@@ -352,7 +350,6 @@
   }
 
   robolectric_library("gurl_junit_tests") {
-    testonly = true
     sources = [ "android/junit/src/org/chromium/url/ShadowGURLTest.java" ]
     deps = [
       ":gurl_java",
@@ -361,7 +358,6 @@
       "//base:base_java_test_support",
       "//base:base_junit_test_support",
       "//base/test:test_support_java",
-      "//third_party/android_deps:robolectric_all_java",
       "//third_party/junit",
     ]
   }
diff --git a/url/url_canon_etc.cc b/url/url_canon_etc.cc
index 53b71ea..851926da 100644
--- a/url/url_canon_etc.cc
+++ b/url/url_canon_etc.cc
@@ -101,7 +101,7 @@
               const Component& scheme,
               CanonOutput* output,
               Component* out_scheme) {
-  if (!scheme.is_nonempty()) {
+  if (scheme.len <= 0) {
     // Scheme is unspecified or empty, convert to empty by appending a colon.
     *out_scheme = Component(output->length(), 0);
     output->push_back(':');
@@ -117,13 +117,12 @@
   // FindAndCompareScheme, which could cause some security checks on
   // schemes to be incorrect.
   bool success = true;
-  size_t begin = static_cast<size_t>(scheme.begin);
-  size_t end = static_cast<size_t>(scheme.end());
-  for (size_t i = begin; i < end; i++) {
+  int end = scheme.end();
+  for (int i = scheme.begin; i < end; i++) {
     UCHAR ch = static_cast<UCHAR>(spec[i]);
     char replacement = 0;
     if (ch < 0x80) {
-      if (i == begin) {
+      if (i == scheme.begin) {
         // Need to do a special check for the first letter of the scheme.
         if (IsSchemeFirstChar(static_cast<unsigned char>(ch)))
           replacement = kSchemeCanonical[ch];
@@ -180,9 +179,8 @@
   out_username->begin = output->length();
   if (username.len > 0) {
     // This will escape characters not valid for the username.
-    AppendStringOfType(&username_spec[username.begin],
-                       static_cast<size_t>(username.len), CHAR_USERINFO,
-                       output);
+    AppendStringOfType(&username_spec[username.begin], username.len,
+                       CHAR_USERINFO, output);
   }
   out_username->len = output->length() - out_username->begin;
 
@@ -191,9 +189,8 @@
   if (password.len > 0) {
     output->push_back(':');
     out_password->begin = output->length();
-    AppendStringOfType(&password_spec[password.begin],
-                       static_cast<size_t>(password.len), CHAR_USERINFO,
-                       output);
+    AppendStringOfType(&password_spec[password.begin], password.len,
+                       CHAR_USERINFO, output);
     out_password->len = output->length() - out_password->begin;
   } else {
     *out_password = Component();
@@ -226,8 +223,7 @@
     // what the error was, and mark the URL as invalid by returning false.
     output->push_back(':');
     out_port->begin = output->length();
-    AppendInvalidNarrowString(spec, static_cast<size_t>(port.begin),
-                              static_cast<size_t>(port.end()), output);
+    AppendInvalidNarrowString(spec, port.begin, port.end(), output);
     out_port->len = output->length() - out_port->begin;
     return false;
   }
@@ -289,7 +285,7 @@
                        const Component& ref,
                        CanonOutput* output,
                        Component* out_ref) {
-  if (!ref.is_valid()) {
+  if (ref.len < 0) {
     // Common case of no ref.
     *out_ref = Component();
     return;
@@ -301,8 +297,8 @@
   out_ref->begin = output->length();
 
   // Now iterate through all the characters, converting to UTF-8 and validating.
-  size_t end = static_cast<size_t>(ref.end());
-  for (size_t i = static_cast<size_t>(ref.begin); i < end; i++) {
+  int end = ref.end();
+  for (int i = ref.begin; i < end; i++) {
     UCHAR current_char = static_cast<UCHAR>(spec[i]);
     if (current_char < 0x80) {
       if (kShouldEscapeCharInFragment[current_char])
diff --git a/url/url_canon_host.cc b/url/url_canon_host.cc
index 5f7bf71..c2cd9d1 100644
--- a/url/url_canon_host.cc
+++ b/url/url_canon_host.cc
@@ -123,15 +123,15 @@
 //    |*has_non_ascii| flag.
 //
 // The return value indicates if the output is a potentially valid host name.
-template <typename INCHAR, typename OUTCHAR>
+template<typename INCHAR, typename OUTCHAR>
 bool DoSimpleHost(const INCHAR* host,
-                  size_t host_len,
+                  int host_len,
                   CanonOutputT<OUTCHAR>* output,
                   bool* has_non_ascii) {
   *has_non_ascii = false;
 
   bool success = true;
-  for (size_t i = 0; i < host_len; ++i) {
+  for (int i = 0; i < host_len; ++i) {
     unsigned int source = host[i];
     if (source == '%') {
       // Unescape first, if possible.
@@ -175,7 +175,7 @@
 }
 
 // Canonicalizes a host that requires IDN conversion. Returns true on success
-bool DoIDNHost(const char16_t* src, size_t src_len, CanonOutput* output) {
+bool DoIDNHost(const char16_t* src, int src_len, CanonOutput* output) {
   int original_output_len = output->length();  // So we can rewind below.
 
   // We need to escape URL before doing IDN conversion, since punicode strings
@@ -202,8 +202,8 @@
   // unescaping. Although we unescaped everything before this function call, if
   // somebody does %00 as fullwidth, ICU will convert this to ASCII.
   bool success = DoSimpleHost(wide_output.data(),
-                              static_cast<size_t>(wide_output.length()), output,
-                              &has_non_ascii);
+                              wide_output.length(),
+                              output, &has_non_ascii);
   if (has_non_ascii) {
     // ICU generated something that DoSimpleHost didn't think looked like
     // ASCII. This is quite rare, but ICU might convert some characters to
@@ -220,8 +220,7 @@
     // ASCII isn't strictly necessary, but DoSimpleHost handles this case
     // anyway so we handle it/
     output->set_length(original_output_len);
-    AppendInvalidNarrowString(wide_output.data(), 0,
-                              static_cast<size_t>(wide_output.length()),
+    AppendInvalidNarrowString(wide_output.data(), 0, wide_output.length(),
                               output);
     return false;
   }
@@ -231,11 +230,8 @@
 // 8-bit convert host to its ASCII version: this converts the UTF-8 input to
 // UTF-16. The has_escaped flag should be set if the input string requires
 // unescaping.
-bool DoComplexHost(const char* host,
-                   size_t host_len,
-                   bool has_non_ascii,
-                   bool has_escaped,
-                   CanonOutput* output) {
+bool DoComplexHost(const char* host, int host_len,
+                   bool has_non_ascii, bool has_escaped, CanonOutput* output) {
   // Save the current position in the output. We may write stuff and rewind it
   // below, so we need to know where to rewind to.
   int begin_length = output->length();
@@ -243,7 +239,7 @@
   // Points to the UTF-8 data we want to convert. This will either be the
   // input or the unescaped version written to |*output| if necessary.
   const char* utf8_source;
-  size_t utf8_source_len;
+  int utf8_source_len;
   bool are_all_escaped_valid = true;
   if (has_escaped) {
     // Unescape before converting to UTF-16 for IDN. We write this into the
@@ -268,7 +264,7 @@
     // Save the pointer into the data was just converted (it may be appended to
     // other data in the output buffer).
     utf8_source = &output->data()[begin_length];
-    utf8_source_len = static_cast<size_t>(output->length() - begin_length);
+    utf8_source_len = output->length() - begin_length;
   } else {
     // We don't need to unescape, use input for IDNization later. (We know the
     // input has non-ASCII, or the simple version would have been called
@@ -284,18 +280,17 @@
   if (!ConvertUTF8ToUTF16(utf8_source, utf8_source_len, &utf16)) {
     // In this error case, the input may or may not be the output.
     StackBuffer utf8;
-    for (size_t i = 0; i < utf8_source_len; i++)
+    for (int i = 0; i < utf8_source_len; i++)
       utf8.push_back(utf8_source[i]);
     output->set_length(begin_length);
-    AppendInvalidNarrowString(utf8.data(), 0,
-                              static_cast<size_t>(utf8.length()), output);
+    AppendInvalidNarrowString(utf8.data(), 0, utf8.length(), output);
     return false;
   }
   output->set_length(begin_length);
 
   // This will call DoSimpleHost which will do normal ASCII canonicalization
   // and also check for IP addresses in the outpt.
-  return DoIDNHost(utf16.data(), static_cast<size_t>(utf16.length()), output) &&
+  return DoIDNHost(utf16.data(), utf16.length(), output) &&
          are_all_escaped_valid;
 }
 
@@ -303,7 +298,7 @@
 // the backend, so we just pass through. The has_escaped flag should be set if
 // the input string requires unescaping.
 bool DoComplexHost(const char16_t* host,
-                   size_t host_len,
+                   int host_len,
                    bool has_non_ascii,
                    bool has_escaped,
                    CanonOutput* output) {
@@ -324,8 +319,8 @@
 
     // Once we convert to UTF-8, we can use the 8-bit version of the complex
     // host handling code above.
-    return DoComplexHost(utf8.data(), static_cast<size_t>(utf8.length()),
-                         has_non_ascii, has_escaped, output);
+    return DoComplexHost(utf8.data(), utf8.length(), has_non_ascii,
+                         has_escaped, output);
   }
 
   // No unescaping necessary, we can safely pass the input to ICU. This
@@ -339,18 +334,16 @@
 bool DoHostSubstring(const CHAR* spec,
                      const Component& host,
                      CanonOutput* output) {
-  DCHECK(host.is_valid());
-
   bool has_non_ascii, has_escaped;
   ScanHostname<CHAR, UCHAR>(spec, host, &has_non_ascii, &has_escaped);
 
   if (has_non_ascii || has_escaped) {
-    return DoComplexHost(&spec[host.begin], static_cast<size_t>(host.len),
-                         has_non_ascii, has_escaped, output);
+    return DoComplexHost(&spec[host.begin], host.len, has_non_ascii,
+                         has_escaped, output);
   }
 
-  const bool success = DoSimpleHost(
-      &spec[host.begin], static_cast<size_t>(host.len), output, &has_non_ascii);
+  const bool success =
+      DoSimpleHost(&spec[host.begin], host.len, output, &has_non_ascii);
   DCHECK(!has_non_ascii);
   return success;
 }
@@ -360,7 +353,7 @@
             const Component& host,
             CanonOutput* output,
             CanonHostInfo* host_info) {
-  if (!host.is_nonempty()) {
+  if (host.len <= 0) {
     // Empty hosts don't need anything.
     host_info->family = CanonHostInfo::NEUTRAL;
     host_info->out_host = Component();
diff --git a/url/url_canon_internal.cc b/url/url_canon_internal.cc
index 192feb9..48a1e74b1 100644
--- a/url/url_canon_internal.cc
+++ b/url/url_canon_internal.cc
@@ -11,19 +11,17 @@
 #include <cstdio>
 #include <string>
 
-#include "base/numerics/safe_conversions.h"
 #include "base/strings/utf_string_conversion_utils.h"
 
 namespace url {
 
 namespace {
 
-template <typename CHAR, typename UCHAR>
-void DoAppendStringOfType(const CHAR* source,
-                          size_t length,
+template<typename CHAR, typename UCHAR>
+void DoAppendStringOfType(const CHAR* source, int length,
                           SharedCharTypes type,
                           CanonOutput* output) {
-  for (size_t i = 0; i < length; i++) {
+  for (int i = 0; i < length; i++) {
     if (static_cast<UCHAR>(source[i]) >= 0x80) {
       // ReadChar will fill the code point with kUnicodeReplacementCharacter
       // when the input is invalid, which is what we want.
@@ -43,12 +41,10 @@
 
 // This function assumes the input values are all contained in 8-bit,
 // although it allows any type. Returns true if input is valid, false if not.
-template <typename CHAR, typename UCHAR>
-void DoAppendInvalidNarrowString(const CHAR* spec,
-                                 size_t begin,
-                                 size_t end,
+template<typename CHAR, typename UCHAR>
+void DoAppendInvalidNarrowString(const CHAR* spec, int begin, int end,
                                  CanonOutput* output) {
-  for (size_t i = begin; i < end; i++) {
+  for (int i = begin; i < end; i++) {
     UCHAR uch = static_cast<UCHAR>(spec[i]);
     if (uch >= 0x80) {
       // Handle UTF-8/16 encodings. This call will correctly handle the error
@@ -102,8 +98,7 @@
       // Convert to UTF-8.
       dest_component->begin = utf8_buffer->length();
       success = ConvertUTF16ToUTF8(&override_source[override_component.begin],
-                                   static_cast<size_t>(override_component.len),
-                                   utf8_buffer);
+                                   override_component.len, utf8_buffer);
       dest_component->len = utf8_buffer->length() - dest_component->begin;
     }
   }
@@ -240,24 +235,26 @@
 
 const base_icu::UChar32 kUnicodeReplacementCharacter = 0xfffd;
 
-void AppendStringOfType(const char* source,
-                        size_t length,
+void AppendStringOfType(const char* source, int length,
                         SharedCharTypes type,
                         CanonOutput* output) {
   DoAppendStringOfType<char, unsigned char>(source, length, type, output);
 }
 
 void AppendStringOfType(const char16_t* source,
-                        size_t length,
+                        int length,
                         SharedCharTypes type,
                         CanonOutput* output) {
   DoAppendStringOfType<char16_t, char16_t>(source, length, type, output);
 }
 
 bool ReadUTFChar(const char* str,
-                 size_t* begin,
-                 size_t length,
+                 int* begin,
+                 int length,
                  base_icu::UChar32* code_point_out) {
+  // This depends on ints and int32s being the same thing. If they're not, it
+  // will fail to compile.
+  // TODO(mmenke): This should probably be fixed.
   if (!base::ReadUnicodeCharacter(str, length, begin, code_point_out) ||
       !base::IsValidCharacter(*code_point_out)) {
     *code_point_out = kUnicodeReplacementCharacter;
@@ -267,9 +264,12 @@
 }
 
 bool ReadUTFChar(const char16_t* str,
-                 size_t* begin,
-                 size_t length,
+                 int* begin,
+                 int length,
                  base_icu::UChar32* code_point_out) {
+  // This depends on ints and int32s being the same thing. If they're not, it
+  // will fail to compile.
+  // TODO(mmenke): This should probably be fixed.
   if (!base::ReadUnicodeCharacter(str, length, begin, code_point_out) ||
       !base::IsValidCharacter(*code_point_out)) {
     *code_point_out = kUnicodeReplacementCharacter;
@@ -278,25 +278,23 @@
   return true;
 }
 
-void AppendInvalidNarrowString(const char* spec,
-                               size_t begin,
-                               size_t end,
+void AppendInvalidNarrowString(const char* spec, int begin, int end,
                                CanonOutput* output) {
   DoAppendInvalidNarrowString<char, unsigned char>(spec, begin, end, output);
 }
 
 void AppendInvalidNarrowString(const char16_t* spec,
-                               size_t begin,
-                               size_t end,
+                               int begin,
+                               int end,
                                CanonOutput* output) {
   DoAppendInvalidNarrowString<char16_t, char16_t>(spec, begin, end, output);
 }
 
 bool ConvertUTF16ToUTF8(const char16_t* input,
-                        size_t input_len,
+                        int input_len,
                         CanonOutput* output) {
   bool success = true;
-  for (size_t i = 0; i < input_len; i++) {
+  for (int i = 0; i < input_len; i++) {
     base_icu::UChar32 code_point;
     success &= ReadUTFChar(input, &i, input_len, &code_point);
     AppendUTF8Value(code_point, output);
@@ -305,10 +303,10 @@
 }
 
 bool ConvertUTF8ToUTF16(const char* input,
-                        size_t input_len,
+                        int input_len,
                         CanonOutputT<char16_t>* output) {
   bool success = true;
-  for (size_t i = 0; i < input_len; i++) {
+  for (int i = 0; i < input_len; i++) {
     base_icu::UChar32 code_point;
     success &= ReadUTFChar(input, &i, input_len, &code_point);
     AppendUTF16Value(code_point, output);
diff --git a/url/url_canon_internal.h b/url/url_canon_internal.h
index ec5b61cb4..def4636 100644
--- a/url/url_canon_internal.h
+++ b/url/url_canon_internal.h
@@ -77,12 +77,11 @@
 
 // Appends the given string to the output, escaping characters that do not
 // match the given |type| in SharedCharTypes.
-void AppendStringOfType(const char* source,
-                        size_t length,
+void AppendStringOfType(const char* source, int length,
                         SharedCharTypes type,
                         CanonOutput* output);
 void AppendStringOfType(const char16_t* source,
-                        size_t length,
+                        int length,
                         SharedCharTypes type,
                         CanonOutput* output);
 
@@ -108,8 +107,8 @@
 // Indicates if the given character is a dot or dot equivalent, returning the
 // number of characters taken by it. This will be one for a literal dot, 3 for
 // an escaped dot. If the character is not a dot, this will return 0.
-template <typename CHAR>
-inline size_t IsDot(const CHAR* spec, size_t offset, size_t end) {
+template<typename CHAR>
+inline int IsDot(const CHAR* spec, int offset, int end) {
   if (spec[offset] == '.') {
     return 1;
   } else if (spec[offset] == '%' && offset + 3 <= end &&
@@ -155,8 +154,8 @@
 // (for a single-byte ASCII character, it will not be changed).
 COMPONENT_EXPORT(URL)
 bool ReadUTFChar(const char* str,
-                 size_t* begin,
-                 size_t length,
+                 int* begin,
+                 int length,
                  base_icu::UChar32* code_point_out);
 
 // Generic To-UTF-8 converter. This will call the given append method for each
@@ -232,8 +231,8 @@
 // (for a single-16-bit-word character, it will not be changed).
 COMPONENT_EXPORT(URL)
 bool ReadUTFChar(const char16_t* str,
-                 size_t* begin,
-                 size_t length,
+                 int* begin,
+                 int length,
                  base_icu::UChar32* code_point_out);
 
 // Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method.
@@ -269,8 +268,8 @@
 // Assumes that ch[begin] is within range in the array, but does not assume
 // that any following characters are.
 inline bool AppendUTF8EscapedChar(const char16_t* str,
-                                  size_t* begin,
-                                  size_t length,
+                                  int* begin,
+                                  int length,
                                   CanonOutput* output) {
   // UTF-16 input. ReadUTFChar will handle invalid characters for us and give
   // us the kUnicodeReplacementCharacter, so we don't have to do special
@@ -282,9 +281,7 @@
 }
 
 // Handles UTF-8 input. See the wide version above for usage.
-inline bool AppendUTF8EscapedChar(const char* str,
-                                  size_t* begin,
-                                  size_t length,
+inline bool AppendUTF8EscapedChar(const char* str, int* begin, int length,
                                   CanonOutput* output) {
   // ReadUTF8Char will handle invalid characters for us and give us the
   // kUnicodeReplacementCharacter, so we don't have to do special checking
@@ -311,10 +308,8 @@
   return c <= 255;
 }
 
-template <typename CHAR>
-inline bool DecodeEscaped(const CHAR* spec,
-                          size_t* begin,
-                          size_t end,
+template<typename CHAR>
+inline bool DecodeEscaped(const CHAR* spec, int* begin, int end,
                           unsigned char* unescaped_value) {
   if (*begin + 3 > end ||
       !Is8BitChar(spec[*begin + 1]) || !Is8BitChar(spec[*begin + 2])) {
@@ -343,13 +338,11 @@
 // This is used in error cases to append invalid output so that it looks
 // approximately correct. Non-error cases should not call this function since
 // the escaping rules are not guaranteed!
-void AppendInvalidNarrowString(const char* spec,
-                               size_t begin,
-                               size_t end,
+void AppendInvalidNarrowString(const char* spec, int begin, int end,
                                CanonOutput* output);
 void AppendInvalidNarrowString(const char16_t* spec,
-                               size_t begin,
-                               size_t end,
+                               int begin,
+                               int end,
                                CanonOutput* output);
 
 // Misc canonicalization helpers ----------------------------------------------
@@ -364,11 +357,11 @@
 // normal.
 COMPONENT_EXPORT(URL)
 bool ConvertUTF16ToUTF8(const char16_t* input,
-                        size_t input_len,
+                        int input_len,
                         CanonOutput* output);
 COMPONENT_EXPORT(URL)
 bool ConvertUTF8ToUTF16(const char* input,
-                        size_t input_len,
+                        int input_len,
                         CanonOutputT<char16_t>* output);
 
 // Converts from UTF-16 to 8-bit using the character set converter. If the
diff --git a/url/url_canon_mailtourl.cc b/url/url_canon_mailtourl.cc
index ff62bea5..f4fe2b4e 100644
--- a/url/url_canon_mailtourl.cc
+++ b/url/url_canon_mailtourl.cc
@@ -57,8 +57,8 @@
     // Copy the path using path URL's more lax escaping rules.
     // We convert to UTF-8 and escape non-ASCII, but leave most
     // ASCII characters alone.
-    size_t end = static_cast<size_t>(parsed.path.end());
-    for (size_t i = static_cast<size_t>(parsed.path.begin); i < end; ++i) {
+    int end = parsed.path.end();
+    for (int i = parsed.path.begin; i < end; ++i) {
       UCHAR uch = static_cast<UCHAR>(source.path[i]);
       if (ShouldEncodeMailboxCharacter<UCHAR>(uch))
         success &= AppendUTF8EscapedChar(source.path, &i, end, output);
diff --git a/url/url_canon_path.cc b/url/url_canon_path.cc
index f50e107..d6fb64b 100644
--- a/url/url_canon_path.cc
+++ b/url/url_canon_path.cc
@@ -101,11 +101,9 @@
 // If the input is "../foo", |after_dot| = 1, |end| = 6, and
 // at the end, |*consumed_len| = 2 for the "./" this function consumed. The
 // original dot length should be handled by the caller.
-template <typename CHAR>
-DotDisposition ClassifyAfterDot(const CHAR* spec,
-                                size_t after_dot,
-                                size_t end,
-                                size_t* consumed_len) {
+template<typename CHAR>
+DotDisposition ClassifyAfterDot(const CHAR* spec, int after_dot,
+                                int end, int* consumed_len) {
   if (after_dot == end) {
     // Single dot at the end.
     *consumed_len = 0;
@@ -117,9 +115,9 @@
     return DIRECTORY_CUR;
   }
 
-  size_t second_dot_len = IsDot(spec, after_dot, end);
+  int second_dot_len = IsDot(spec, after_dot, end);
   if (second_dot_len) {
-    size_t after_second_dot = after_dot + second_dot_len;
+    int after_second_dot = after_dot + second_dot_len;
     if (after_second_dot == end) {
       // Double dot at the end.
       *consumed_len = second_dot_len;
@@ -195,10 +193,10 @@
 // ends with a '%' followed by one or two characters, and the '%' is the one
 // pointed to by |last_invalid_percent_index|.  The last character in the string
 // was just unescaped.
-template <typename CHAR>
+template<typename CHAR>
 void CheckForNestedEscapes(const CHAR* spec,
-                           size_t next_input_index,
-                           size_t input_len,
+                           int next_input_index,
+                           int input_len,
                            int last_invalid_percent_index,
                            CanonOutput* output) {
   const int length = output->length();
@@ -220,10 +218,9 @@
   }
 
   // Now output ends like "%cc".  Try to unescape this.
-  size_t begin = static_cast<size_t>(last_invalid_percent_index);
+  int begin = last_invalid_percent_index;
   unsigned char temp;
-  if (DecodeEscaped(output->data(), &begin,
-                    static_cast<size_t>(output->length()), &temp)) {
+  if (DecodeEscaped(output->data(), &begin, output->length(), &temp)) {
     // New escape sequence found.  Overwrite the characters following the '%'
     // with "25", and push_back() the one or two characters that were following
     // the '%' when we were called.
@@ -255,10 +252,7 @@
                            const Component& path,
                            int path_begin_in_output,
                            CanonOutput* output) {
-  if (!path.is_nonempty())
-    return true;
-
-  size_t end = static_cast<size_t>(path.end());
+  int end = path.end();
 
   // We use this variable to minimize the amount of work done when unescaping --
   // we'll only call CheckForNestedEscapes() when this points at one of the last
@@ -266,7 +260,7 @@
   int last_invalid_percent_index = INT_MIN;
 
   bool success = true;
-  for (size_t i = static_cast<size_t>(path.begin); i < end; i++) {
+  for (int i = path.begin; i < end; i++) {
     DCHECK_LT(last_invalid_percent_index, output->length());
     UCHAR uch = static_cast<UCHAR>(spec[i]);
     if (sizeof(CHAR) > 1 && uch >= 0x80) {
@@ -282,7 +276,7 @@
       unsigned char flags = kPathCharLookup[out_ch];
       if (flags & SPECIAL) {
         // Needs special handling of some sort.
-        size_t dotlen;
+        int dotlen;
         if ((dotlen = IsDot(spec, i, end)) > 0) {
           // See if this dot was preceded by a slash in the output.
           //
@@ -293,7 +287,7 @@
           if (output->length() > path_begin_in_output &&
               output->at(output->length() - 1) == '/') {
             // Slash followed by a dot, check to see if this is means relative
-            size_t consumed_len;
+            int consumed_len;
             switch (ClassifyAfterDot<CHAR>(spec, i + dotlen, end,
                                            &consumed_len)) {
               case NOT_A_DIRECTORY:
diff --git a/url/url_canon_pathurl.cc b/url/url_canon_pathurl.cc
index d8d65f33..e726cfb 100644
--- a/url/url_canon_pathurl.cc
+++ b/url/url_canon_pathurl.cc
@@ -32,8 +32,8 @@
     // https://url.spec.whatwg.org/#cannot-be-a-base-url-path-state
     // https://url.spec.whatwg.org/#c0-control-percent-encode-set
     new_component->begin = output->length();
-    size_t end = static_cast<size_t>(component.end());
-    for (size_t i = static_cast<size_t>(component.begin); i < end; i++) {
+    int end = component.end();
+    for (int i = component.begin; i < end; i++) {
       UCHAR uch = static_cast<UCHAR>(source[i]);
       if (uch < 0x20 || uch > 0x7E)
         AppendUTF8EscapedChar(source, &i, end, output);
diff --git a/url/url_canon_query.cc b/url/url_canon_query.cc
index d23b45f..b3a1118 100644
--- a/url/url_canon_query.cc
+++ b/url/url_canon_query.cc
@@ -72,12 +72,10 @@
                   const Component& query,
                   CharsetConverter* converter,
                   CanonOutput* output) {
-  DCHECK(query.is_valid());
   // This function will replace any misencoded values with the invalid
   // character. This is what we want so we don't have to check for error.
   RawCanonOutputW<1024> utf16;
-  ConvertUTF8ToUTF16(&spec[query.begin], static_cast<size_t>(query.len),
-                     &utf16);
+  ConvertUTF8ToUTF16(&spec[query.begin], query.len, &utf16);
   converter->ConvertFromUTF16(utf16.data(), utf16.length(), output);
 }
 
@@ -88,9 +86,7 @@
                   const Component& query,
                   CharsetConverter* converter,
                   CanonOutput* output) {
-  DCHECK(query.is_valid());
-  converter->ConvertFromUTF16(&spec[query.begin],
-                              static_cast<size_t>(query.len), output);
+  converter->ConvertFromUTF16(&spec[query.begin], query.len, output);
 }
 
 template<typename CHAR, typename UCHAR>
@@ -113,8 +109,7 @@
 
     } else {
       // No converter, do our own UTF-8 conversion.
-      AppendStringOfType(&spec[query.begin], static_cast<size_t>(query.len),
-                         CHAR_QUERY, output);
+      AppendStringOfType(&spec[query.begin], query.len, CHAR_QUERY, output);
     }
   }
 }
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index 96aa55a..f6ac9d4 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -173,9 +173,9 @@
       out_str.clear();
       StdStringCanonOutput output(&out_str);
 
-      size_t input_len = strlen(utf_cases[i].input8);
+      int input_len = static_cast<int>(strlen(utf_cases[i].input8));
       bool success = true;
-      for (size_t ch = 0; ch < input_len; ch++) {
+      for (int ch = 0; ch < input_len; ch++) {
         success &= AppendUTF8EscapedChar(utf_cases[i].input8, &ch, input_len,
                                          &output);
       }
@@ -189,9 +189,9 @@
 
       std::u16string input_str(
           test_utils::TruncateWStringToUTF16(utf_cases[i].input16));
-      size_t input_len = input_str.length();
+      int input_len = static_cast<int>(input_str.length());
       bool success = true;
-      for (size_t ch = 0; ch < input_len; ch++) {
+      for (int ch = 0; ch < input_len; ch++) {
         success &= AppendUTF8EscapedChar(input_str.c_str(), &ch, input_len,
                                          &output);
       }
diff --git a/url/url_util.cc b/url/url_util.cc
index cd8e2e1..1f0de84 100644
--- a/url/url_util.cc
+++ b/url/url_util.cc
@@ -811,15 +811,11 @@
                               int length,
                               DecodeURLMode mode,
                               CanonOutputW* output) {
-  if (length <= 0)
-    return;
-
   STACK_UNINITIALIZED RawCanonOutputT<char> unescaped_chars;
-  size_t length_size_t = static_cast<size_t>(length);
-  for (size_t i = 0; i < length_size_t; i++) {
+  for (int i = 0; i < length; i++) {
     if (input[i] == '%') {
       unsigned char ch;
-      if (DecodeEscaped(input, &i, length_size_t, &ch)) {
+      if (DecodeEscaped(input, &i, length, &ch)) {
         unescaped_chars.push_back(ch);
       } else {
         // Invalid escape sequence, copy the percent literal.
@@ -834,20 +830,18 @@
   int output_initial_length = output->length();
   // Convert that 8-bit to UTF-16. It's not clear IE does this at all to
   // JavaScript URLs, but Firefox and Safari do.
-  size_t unescaped_length = static_cast<size_t>(unescaped_chars.length());
-  for (size_t i = 0; i < unescaped_length; i++) {
-    unsigned char uch =
-        static_cast<unsigned char>(unescaped_chars.at(static_cast<int>(i)));
+  for (int i = 0; i < unescaped_chars.length(); i++) {
+    unsigned char uch = static_cast<unsigned char>(unescaped_chars.at(i));
     if (uch < 0x80) {
       // Non-UTF-8, just append directly
       output->push_back(uch);
     } else {
       // next_ch will point to the last character of the decoded
       // character.
-      size_t next_character = i;
+      int next_character = i;
       base_icu::UChar32 code_point;
-      if (ReadUTFChar(unescaped_chars.data(), &next_character, unescaped_length,
-                      &code_point)) {
+      if (ReadUTFChar(unescaped_chars.data(), &next_character,
+                      unescaped_chars.length(), &code_point)) {
         // Valid UTF-8 character, convert to UTF-16.
         AppendUTF16Value(code_point, output);
         i = next_character;
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn
index 1a534bcd..f18f00c 100644
--- a/weblayer/browser/java/BUILD.gn
+++ b/weblayer/browser/java/BUILD.gn
@@ -409,7 +409,6 @@
 }
 
 robolectric_library("junit_test_support") {
-  testonly = true
   deps = [
     ":java",
     "//components/payments/content/android:java",
@@ -419,7 +418,6 @@
     "//content/public/android:content_java",
     "//mojo/public/java:bindings_java",
     "//mojo/public/java:system_java",
-    "//third_party/android_deps:robolectric_all_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/blink/public/mojom:android_mojo_bindings_java",
     "//third_party/mockito:mockito_java",