diff --git a/DEPS b/DEPS
index 7d57a51..9dbc2a0 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': '068fc2cfc1ccee45f1927c91847a757270f02dec',
+  'skia_revision': '1716e84b8f5da34319d3370d307ad97c9d19ff3d',
   # 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': '803d5313a8ce5bdf5d165d423e1bc15106f694c8',
+  'v8_revision': '5397eefc0cee7e1b6ea4a794853ca772222a1dfe',
   # 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': 'a4e00c64528d21f5fab3ab4900357d31ee3dbdc1',
+  'angle_revision': '94bbb40a42cdbe7700739f733df9df2835ba453e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -307,7 +307,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:8.20220707.1.1',
+  'fuchsia_version': 'version:8.20220707.3.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -331,7 +331,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '8a9192f68ef0100649502bd8fe17df7f51211521',
+  'freetype_revision': '7c151abb6903ddb9c9ed5a1c7b962819c1b2d36f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # 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': '6b65e0427dd4018366a81be0f2f9704e0932400c',
+  'catapult_revision': 'd7cbf23b7d50ba1069dada756ad736fd523ee015',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -359,7 +359,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '70130c820e36839b359b1843a09875511f14e93b',
+  'devtools_frontend_revision': '1aa36584d580ed5aa2caf7a8533f2c89b16ab66b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -929,7 +929,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'Wp5QJnaBXtZUKJgQC5gmoQwAjWWDE6cBkjRAoSu8IIoC',
+          'version': 'jh10aKp2in7ld755-cUy8ZafrE-iVdH__bQjHMhmTA4C',
       },
     ],
     'condition': 'checkout_android',
@@ -1162,7 +1162,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '9b6bdd148e69033bb5d3a1c28da8740f56a32359',
+      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '98ffe74a1036ae363a12dc57d14dd88535504dcb',
       'condition': 'checkout_linux',
   },
 
@@ -1731,10 +1731,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'e58ed2132aa47ac110a4cce1763abfa34f4fa34e',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a6bab72c7259ca3131b00a856cd9be23fc15bbd3',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a65914cd9634244099dc6105de5f2b33f2c1c823',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '9b29b874708f0567951f0c8923fc1af2e4f9b5e7',
+    Var('webrtc_git') + '/src.git' + '@' + '401158ba9a267ed2fb986bc4b89e84f490aae4cc',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1807,7 +1807,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@57532da32c2a6e4cb1a5f471a7426274c93091b0',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@748ff790b2e1de7806d4b90865223e936cdf5376',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/clipboard/clipboard_history_controller_impl.cc b/ash/clipboard/clipboard_history_controller_impl.cc
index 621bfbf..4b78451 100644
--- a/ash/clipboard/clipboard_history_controller_impl.cc
+++ b/ash/clipboard/clipboard_history_controller_impl.cc
@@ -32,6 +32,8 @@
 #include "base/location.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "base/notreached.h"
 #include "base/one_shot_event.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/utf_string_conversions.h"
@@ -103,6 +105,36 @@
   std::move(barrier_callback).Run();
 }
 
+// Emits a user action indicating that the clipboard history item at menu index
+// `command_id` was pasted.
+void RecordMenuIndexPastedUserAction(int command_id) {
+  // Per guidance in user_metrics.h, use string literals for action names.
+  switch (command_id) {
+    case 1:
+      base::RecordAction(
+          base::UserMetricsAction("Ash_ClipboardHistory_PastedItem1"));
+      break;
+    case 2:
+      base::RecordAction(
+          base::UserMetricsAction("Ash_ClipboardHistory_PastedItem2"));
+      break;
+    case 3:
+      base::RecordAction(
+          base::UserMetricsAction("Ash_ClipboardHistory_PastedItem3"));
+      break;
+    case 4:
+      base::RecordAction(
+          base::UserMetricsAction("Ash_ClipboardHistory_PastedItem4"));
+      break;
+    case 5:
+      base::RecordAction(
+          base::UserMetricsAction("Ash_ClipboardHistory_PastedItem5"));
+      break;
+    default:
+      NOTREACHED();
+  }
+}
+
 using ClipboardHistoryPasteType =
     ash::ClipboardHistoryControllerImpl::ClipboardHistoryPasteType;
 bool IsPlainTextPaste(ClipboardHistoryPasteType paste_type) {
@@ -715,9 +747,15 @@
 void ClipboardHistoryControllerImpl::PasteMenuItemData(
     int command_id,
     ClipboardHistoryPasteType paste_type) {
+  // Record the paste item's history list index in a histogram to get a
+  // distribution of where in the list users paste from.
   UMA_HISTOGRAM_ENUMERATION(
       "Ash.ClipboardHistory.ContextMenu.MenuOptionSelected", command_id,
       ClipboardHistoryUtil::kMaxCommandId);
+  // Record the paste item's history list index as a user action to analyze
+  // usage patterns, e.g., how frequently the same index is pasted multiple
+  // times in a row.
+  RecordMenuIndexPastedUserAction(command_id);
 
   // Deactivate ClipboardImageModelFactory prior to pasting to ensure that any
   // modifications to the clipboard for HTML rendering purposes are reversed.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 423ffae..92f2881 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -2345,6 +2345,10 @@
   return use_trilinear_filtering;
 }
 
+bool IsUploadOfficeToCloudEnabled() {
+  return base::FeatureList::IsEnabled(kUploadOfficeToCloud);
+}
+
 bool IsUseStorkSmdsServerAddressEnabled() {
   return base::FeatureList::IsEnabled(kUseStorkSmdsServerAddress);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 8eacb301..c580602 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -705,6 +705,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFileManagerFuseBoxEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFileManagerFuseBoxDebugEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFileManagerSwaEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFilesWebDriveOfficeEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFirmwareUpdaterAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFloatingWorkspaceEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFullscreenAfterUnlockAllowed();
@@ -832,6 +833,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTouchscreenInDiagnosticsAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTrafficCountersEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTrilinearFilteringEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUploadOfficeToCloudEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUseStorkSmdsServerAddressEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFastRefreshEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFullScreenPreviewEnabled();
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc
index 87e8d91..5c87bf4 100644
--- a/ash/public/cpp/app_list/app_list_features.cc
+++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -31,8 +31,6 @@
                                           base::FEATURE_ENABLED_BY_DEFAULT};
 const base::Feature kEnableExactMatchForNonLatinLocale{
     "EnableExactMatchForNonLatinLocale", base::FEATURE_ENABLED_BY_DEFAULT};
-const base::Feature kEnableLauncherSearchNormalization{
-    "EnableLauncherSearchNormalization", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kCategoricalSearch{"CategoricalSearch",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 // DO NOT REMOVE: Tast integration tests use this feature. (See crbug/1340267)
@@ -85,10 +83,6 @@
   return base::FeatureList::IsEnabled(kEnableExactMatchForNonLatinLocale);
 }
 
-bool IsLauncherSearchNormalizationEnabled() {
-  return base::FeatureList::IsEnabled(kEnableLauncherSearchNormalization);
-}
-
 std::string AppSearchResultRankerPredictorName() {
   const std::string predictor_name = base::GetFieldTrialParamValueByFeature(
       kEnableZeroStateAppsRanker, "app_search_result_ranker_predictor_name");
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h
index 2a8e7fec..cf389990 100644
--- a/ash/public/cpp/app_list/app_list_features.h
+++ b/ash/public/cpp/app_list/app_list_features.h
@@ -53,9 +53,6 @@
 // Enables launcher search results for OS settings.
 ASH_PUBLIC_EXPORT extern const base::Feature kLauncherSettingsSearch;
 
-// Enables normalization of search results in the launcher.
-ASH_PUBLIC_EXPORT extern const base::Feature kEnableLauncherSearchNormalization;
-
 // Enables categorical search in the launcher.
 ASH_PUBLIC_EXPORT extern const base::Feature kCategoricalSearch;
 
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h
index 5def982..c54b646 100644
--- a/ash/public/cpp/wallpaper/wallpaper_controller.h
+++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -85,7 +85,8 @@
                                   const std::string& file_name,
                                   WallpaperLayout layout,
                                   const gfx::ImageSkia& image,
-                                  bool preview_mode) = 0;
+                                  bool preview_mode,
+                                  const std::string& file_path) = 0;
 
   // Sets the wallpaper at |params.asset_id|, |params.url| and
   // |params.collection_id| as the active wallpaper for the user at
diff --git a/ash/public/cpp/wallpaper/wallpaper_info.cc b/ash/public/cpp/wallpaper/wallpaper_info.cc
index 8dc0ac025..7bcc62a 100644
--- a/ash/public/cpp/wallpaper/wallpaper_info.cc
+++ b/ash/public/cpp/wallpaper/wallpaper_info.cc
@@ -46,8 +46,13 @@
 WallpaperInfo::WallpaperInfo(const std::string& in_location,
                              WallpaperLayout in_layout,
                              WallpaperType in_type,
-                             const base::Time& in_date)
-    : location(in_location), layout(in_layout), type(in_type), date(in_date) {}
+                             const base::Time& in_date,
+                             const std::string& in_user_file_path)
+    : location(in_location),
+      user_file_path(in_user_file_path),
+      layout(in_layout),
+      type(in_type),
+      date(in_date) {}
 
 WallpaperInfo::WallpaperInfo(const WallpaperInfo& other) = default;
 WallpaperInfo& WallpaperInfo::operator=(const WallpaperInfo& other) = default;
@@ -71,6 +76,9 @@
       return location == other.location && layout == other.layout &&
              collection_id == other.collection_id;
     case WallpaperType::kCustomized:
+      return type == other.type && layout == other.layout &&
+             location == other.location &&
+             user_file_path == other.user_file_path;
     case WallpaperType::kDefault:
     case WallpaperType::kPolicy:
     case WallpaperType::kThirdParty:
@@ -91,6 +99,7 @@
 std::ostream& operator<<(std::ostream& os, const WallpaperInfo& info) {
   os << "WallpaperInfo:" << std::endl;
   os << "  location: " << info.location << std::endl;
+  os << "  user_file_path: " << info.user_file_path << std::endl;
   os << "  layout: " << info.layout << std::endl;
   os << "  type: " << static_cast<int>(info.type) << std::endl;
   os << "  date: " << info.date << std::endl;
diff --git a/ash/public/cpp/wallpaper/wallpaper_info.h b/ash/public/cpp/wallpaper/wallpaper_info.h
index 650cd91..0c7368d 100644
--- a/ash/public/cpp/wallpaper/wallpaper_info.h
+++ b/ash/public/cpp/wallpaper/wallpaper_info.h
@@ -28,7 +28,8 @@
   WallpaperInfo(const std::string& in_location,
                 WallpaperLayout in_layout,
                 WallpaperType in_type,
-                const base::Time& in_date);
+                const base::Time& in_date,
+                const std::string& in_user_file_path = "");
 
   WallpaperInfo(const WallpaperInfo& other);
   WallpaperInfo& operator=(const WallpaperInfo& other);
@@ -46,6 +47,11 @@
   // (corresponding to user wallpaper_files_id), online wallpaper URL, or
   // Google Photos id.
   std::string location;
+  // user_file_path is the full path of the wallpaper file and is used as
+  // the new CurrentWallpaper key. This field is required as the old key which
+  // was set to the filename part made the UI mistakenly highlight multiple
+  // files with the same name as the currently set wallpaper (b/229420564).
+  std::string user_file_path;
   WallpaperLayout layout;
   WallpaperType type;
   base::Time date;
diff --git a/ash/system/human_presence/lock_on_leave_controller.cc b/ash/system/human_presence/lock_on_leave_controller.cc
index 1f00f81..e4b197d 100644
--- a/ash/system/human_presence/lock_on_leave_controller.cc
+++ b/ash/system/human_presence/lock_on_leave_controller.cc
@@ -18,6 +18,10 @@
   const auto config = hps::GetEnableLockOnLeaveConfig();
   if (config.has_value()) {
     HumanPresenceDBusClient::Get()->EnableHpsSense(config.value());
+    LOG(ERROR) << "LockOnLeaveController: enabling HpsSense from chrome.";
+  } else {
+    LOG(ERROR)
+        << "LockOnLeaveController: couldn't parse HpsSense configuration.";
   }
 }
 
diff --git a/ash/system/human_presence/snooping_protection_controller.cc b/ash/system/human_presence/snooping_protection_controller.cc
index 6021d15..43935b8d 100644
--- a/ash/system/human_presence/snooping_protection_controller.cc
+++ b/ash/system/human_presence/snooping_protection_controller.cc
@@ -262,9 +262,12 @@
     const absl::optional<hps::FeatureConfig> config =
         hps::GetEnableSnoopingProtectionConfig();
     if (!config.has_value()) {
-      LOG(ERROR) << "Couldn't parse notify configuration";
+      LOG(ERROR) << "SnoopingProtectionController: couldn't parse HpsNotify "
+                    "configuration.";
       return;
     }
+    LOG(ERROR)
+        << "SnoopingProtectionController: enabling HpsNotify from chrome.";
 
     HumanPresenceDBusClient::Get()->EnableHpsNotify(*config);
 
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index c15b7b3..fd7a73a 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1021,7 +1021,8 @@
                                                  const std::string& file_name,
                                                  WallpaperLayout layout,
                                                  const gfx::ImageSkia& image,
-                                                 bool preview_mode) {
+                                                 bool preview_mode,
+                                                 const std::string& file_path) {
   DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted());
   if (!CanSetUserWallpaper(account_id))
     return;
@@ -1032,19 +1033,19 @@
     confirm_preview_wallpaper_callback_ =
         base::BindOnce(&WallpaperControllerImpl::SaveAndSetWallpaper,
                        weak_factory_.GetWeakPtr(), account_id, file_name,
-                       WallpaperType::kCustomized, layout,
+                       file_path, WallpaperType::kCustomized, layout,
                        /*show_wallpaper=*/false, image);
     reload_preview_wallpaper_callback_ = base::BindRepeating(
         &WallpaperControllerImpl::ShowWallpaperImage,
         weak_factory_.GetWeakPtr(), image,
         WallpaperInfo{/*in_location=*/std::string(), layout,
-                      WallpaperType::kCustomized, base::Time::Now()},
+                      WallpaperType::kCustomized, base::Time::Now(), file_path},
         /*preview_mode=*/true, /*always_on_top=*/false);
     // Show the preview wallpaper.
     reload_preview_wallpaper_callback_.Run();
   } else {
     SaveAndSetWallpaperWithCompletion(
-        account_id, file_name, WallpaperType::kCustomized, layout,
+        account_id, file_name, file_path, WallpaperType::kCustomized, layout,
         /*show_wallpaper=*/is_active_user, image,
         base::BindOnce(
             &WallpaperControllerImpl::SaveWallpaperToDriveFsAndSyncInfo,
@@ -1294,8 +1295,8 @@
   const bool show_wallpaper = IsActiveUser(account_id);
   image_util::DecodeImageCallback callback = base::BindOnce(
       &WallpaperControllerImpl::SaveAndSetWallpaper, weak_factory_.GetWeakPtr(),
-      account_id, kPolicyWallpaperFile, WallpaperType::kPolicy,
-      WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
+      account_id, kPolicyWallpaperFile, /*file_path=*/"",
+      WallpaperType::kPolicy, WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
 
   if (bypass_decode_for_testing_) {
     std::move(callback).Run(CreateSolidColorWallpaper(kDefaultWallpaperColor));
@@ -1331,8 +1332,9 @@
   bool allowed_to_show_wallpaper = IsActiveUser(account_id);
 
   if (allowed_to_set_wallpaper) {
-    SaveAndSetWallpaper(account_id, file_name, WallpaperType::kCustomized,
-                        layout, allowed_to_show_wallpaper, image);
+    SaveAndSetWallpaper(account_id, file_name, /*file_path=*/"",
+                        WallpaperType::kCustomized, layout,
+                        allowed_to_show_wallpaper, image);
   }
   return allowed_to_set_wallpaper && allowed_to_show_wallpaper;
 }
@@ -2480,17 +2482,20 @@
 
 void WallpaperControllerImpl::SaveAndSetWallpaper(const AccountId& account_id,
                                                   const std::string& file_name,
+                                                  const std::string& file_path,
                                                   WallpaperType type,
                                                   WallpaperLayout layout,
                                                   bool show_wallpaper,
                                                   const gfx::ImageSkia& image) {
-  SaveAndSetWallpaperWithCompletion(account_id, file_name, type, layout,
-                                    show_wallpaper, image, base::DoNothing());
+  SaveAndSetWallpaperWithCompletion(account_id, file_name, file_path, type,
+                                    layout, show_wallpaper, image,
+                                    base::DoNothing());
 }
 
 void WallpaperControllerImpl::SaveAndSetWallpaperWithCompletion(
     const AccountId& account_id,
     const std::string& file_name,
+    const std::string& file_path,
     WallpaperType type,
     WallpaperLayout layout,
     bool show_wallpaper,
@@ -2501,14 +2506,15 @@
         account_id,
         base::BindOnce(
             &WallpaperControllerImpl::SaveAndSetWallpaperWithCompletionFilesId,
-            weak_factory_.GetWeakPtr(), account_id, file_name, type, layout,
-            show_wallpaper, image, std::move(image_saved_callback)));
+            weak_factory_.GetWeakPtr(), account_id, file_name, file_path, type,
+            layout, show_wallpaper, image, std::move(image_saved_callback)));
   }
 }
 
 void WallpaperControllerImpl::SaveAndSetWallpaperWithCompletionFilesId(
     const AccountId& account_id,
     const std::string& file_name,
+    const std::string& file_path,
     WallpaperType type,
     WallpaperLayout layout,
     bool show_wallpaper,
@@ -2527,7 +2533,8 @@
       base::FilePath(wallpaper_files_id).Append(file_name).value();
   // User's custom wallpaper path is determined by relative path and the
   // appropriate wallpaper resolution.
-  WallpaperInfo info = {relative_path, layout, type, base::Time::Now()};
+  WallpaperInfo info = {relative_path, layout, type, base::Time::Now(),
+                        file_path};
   if (!SetUserWallpaperInfo(account_id, info)) {
     LOG(ERROR) << "Setting user wallpaper info fails. This should never happen "
                   "except in tests.";
@@ -2581,7 +2588,7 @@
   std::move(callback).Run(success);
   if (success) {
     SetCustomWallpaper(account_id, path.BaseName().value(), layout, image,
-                       preview_mode);
+                       preview_mode, path.value());
   }
 }
 
@@ -3174,10 +3181,11 @@
   }
   base::FilePath path_in_prefs = base::FilePath(info.location);
   std::string file_name = path_in_prefs.BaseName().value();
+  std::string file_path = info.user_file_path;
   ReadAndDecodeWallpaper(
       base::BindOnce(&WallpaperControllerImpl::SaveAndSetWallpaper,
                      weak_factory_.GetWeakPtr(), account_id, file_name,
-                     WallpaperType::kCustomized, info.layout,
+                     file_path, WallpaperType::kCustomized, info.layout,
                      /*show_wallpaper=*/true),
       drivefs_path);
 }
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h
index 66527f7..cb7b470 100644
--- a/ash/wallpaper/wallpaper_controller_impl.h
+++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -238,7 +238,8 @@
                           const std::string& file_name,
                           WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode) override;
+                          bool preview_mode,
+                          const std::string& file_path = "") override;
   void SetOnlineWallpaper(const OnlineWallpaperParams& params,
                           SetWallpaperCallback callback) override;
   void SetOnlineWallpaperIfExists(const OnlineWallpaperParams& params,
@@ -542,6 +543,7 @@
   // updates the cache.
   void SaveAndSetWallpaper(const AccountId& account_id,
                            const std::string& file_name,
+                           const std::string& file_path,
                            WallpaperType type,
                            WallpaperLayout layout,
                            bool show_wallpaper,
@@ -551,6 +553,7 @@
   void SaveAndSetWallpaperWithCompletion(
       const AccountId& account_id,
       const std::string& file_name,
+      const std::string& file_path,
       WallpaperType type,
       WallpaperLayout layout,
       bool show_wallpaper,
@@ -560,6 +563,7 @@
   void SaveAndSetWallpaperWithCompletionFilesId(
       const AccountId& account_id,
       const std::string& file_name,
+      const std::string& file_path,
       WallpaperType type,
       WallpaperLayout layout,
       bool show_wallpaper,
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index bfcbdd2..ca549a5 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -307,6 +307,9 @@
       base::NumberToString(info.date.ToInternalValue()));
   wallpaper_info_dict.SetStringKey(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringKey(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntKey(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntKey(WallpaperPrefManager::kNewWallpaperTypeNodeName,
@@ -3419,6 +3422,9 @@
           base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()));
   wallpaper_info_dict.SetStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, "location");
+  wallpaper_info_dict.SetStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      "user_file_path");
   wallpaper_info_dict.SetIntPath(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName,
       WallpaperLayout::WALLPAPER_LAYOUT_CENTER);
diff --git a/ash/wallpaper/wallpaper_pref_manager.cc b/ash/wallpaper/wallpaper_pref_manager.cc
index 9facb8c..acad384 100644
--- a/ash/wallpaper/wallpaper_pref_manager.cc
+++ b/ash/wallpaper/wallpaper_pref_manager.cc
@@ -120,6 +120,8 @@
   // Use temporary variables to keep |info| untouched in the error case.
   const std::string* location = info_dict->FindStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName);
+  const std::string* file_path = info_dict->FindStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName);
   absl::optional<int> layout =
       info_dict->FindIntPath(WallpaperPrefManager::kNewWallpaperLayoutNodeName);
   absl::optional<int> type =
@@ -146,6 +148,7 @@
     return false;
 
   info->location = *location;
+  info->user_file_path = *file_path;
   info->layout = static_cast<WallpaperLayout>(layout.value());
   // TODO(skau): Switch to TimeFromValue
   info->date =
@@ -209,6 +212,9 @@
   }
   wallpaper_info_dict.SetStringPath(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringPath(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntPath(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntPath(
@@ -545,6 +551,8 @@
 const char WallpaperPrefManager::kNewWallpaperDedupKeyNodeName[] = "dedup_key";
 const char WallpaperPrefManager::kNewWallpaperLayoutNodeName[] = "layout";
 const char WallpaperPrefManager::kNewWallpaperLocationNodeName[] = "file";
+const char WallpaperPrefManager::kNewWallpaperUserFilePathNodeName[] =
+    "file_path";
 const char WallpaperPrefManager::kNewWallpaperTypeNodeName[] = "type";
 const char WallpaperPrefManager::kNewWallpaperUnitIdNodeName[] = "unit_id";
 const char WallpaperPrefManager::kNewWallpaperVariantListNodeName[] =
diff --git a/ash/wallpaper/wallpaper_pref_manager.h b/ash/wallpaper/wallpaper_pref_manager.h
index c6b2fb54..1a3cf54 100644
--- a/ash/wallpaper/wallpaper_pref_manager.h
+++ b/ash/wallpaper/wallpaper_pref_manager.h
@@ -63,6 +63,7 @@
   static const char kNewWallpaperDedupKeyNodeName[];
   static const char kNewWallpaperLayoutNodeName[];
   static const char kNewWallpaperLocationNodeName[];
+  static const char kNewWallpaperUserFilePathNodeName[];
   static const char kNewWallpaperTypeNodeName[];
   static const char kNewWallpaperUnitIdNodeName[];
   static const char kNewWallpaperVariantListNodeName[];
diff --git a/ash/wallpaper/wallpaper_pref_manager_unittest.cc b/ash/wallpaper/wallpaper_pref_manager_unittest.cc
index 6517ef1..15870a6 100644
--- a/ash/wallpaper/wallpaper_pref_manager_unittest.cc
+++ b/ash/wallpaper/wallpaper_pref_manager_unittest.cc
@@ -77,6 +77,9 @@
       base::NumberToString(info.date.ToInternalValue()));
   wallpaper_info_dict.SetStringKey(
       WallpaperPrefManager::kNewWallpaperLocationNodeName, info.location);
+  wallpaper_info_dict.SetStringKey(
+      WallpaperPrefManager::kNewWallpaperUserFilePathNodeName,
+      info.user_file_path);
   wallpaper_info_dict.SetIntKey(
       WallpaperPrefManager::kNewWallpaperLayoutNodeName, info.layout);
   wallpaper_info_dict.SetIntKey(WallpaperPrefManager::kNewWallpaperTypeNodeName,
diff --git a/ash/webui/personalization_app/resources/trusted/utils.ts b/ash/webui/personalization_app/resources/trusted/utils.ts
index d40f621..cc0bad6 100644
--- a/ash/webui/personalization_app/resources/trusted/utils.ts
+++ b/ash/webui/personalization_app/resources/trusted/utils.ts
@@ -43,8 +43,7 @@
     return key === kDefaultImageSymbol;
   }
   if (isFilePath(image)) {
-    // TODO(b/229420564): Update key extraction for local images.
-    return key === image.path.substr(image.path.lastIndexOf('/') + 1);
+    return key === image.path;
   }
   assert(isGooglePhotosPhoto(image));
   // NOTE: Old clients may not support |dedupKey| when setting Google Photos
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
index 81ab9dd22..74085561 100644
--- a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
+++ b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
@@ -175,7 +175,7 @@
     }
     return (isFilePath(pendingSelected) &&
                 image.path === pendingSelected.path ||
-            !!currentSelected && image.path.endsWith(currentSelected.key) &&
+            !!currentSelected && image.path === currentSelected.key &&
                 !pendingSelected)
                .toString() as 'true' |
         'false';
diff --git a/ash/wm/multitask_menu_nudge_controller.cc b/ash/wm/multitask_menu_nudge_controller.cc
index b114962..c69c871 100644
--- a/ash/wm/multitask_menu_nudge_controller.cc
+++ b/ash/wm/multitask_menu_nudge_controller.cc
@@ -154,13 +154,19 @@
   if (!frame_header)
     return;
 
+  // The anchor is the button on the header that serves as the maximize or
+  // restore button (depending on the window state).
+  auto* anchor_view = frame_header->caption_button_container()->size_button();
+  DCHECK(anchor_view);
+
+  // If either the window or anchor is not visible, do not show the nudge.
+  if (!window->IsVisible() || !anchor_view->IsDrawn())
+    return;
+
   window_ = window;
   window_observation_.Observe(window_);
 
-  // The anchor is the button on the header that serves as the maximize or
-  // restore button (depending on the window state).
-  anchor_view_ = frame_header->caption_button_container()->size_button();
-  DCHECK(anchor_view_);
+  anchor_view_ = anchor_view;
 
   nudge_widget_ = CreateWidget(window_->parent());
   nudge_widget_->Show();
@@ -171,6 +177,7 @@
   window_->parent()->layer()->Add(pulse_layer_.get());
 
   UpdateWidgetAndPulse();
+  DCHECK(nudge_widget_);
 
   // Fade the educational nudge in.
   ui::Layer* layer = nudge_widget_->GetLayer();
diff --git a/ash/wm/multitask_menu_nudge_controller_unittest.cc b/ash/wm/multitask_menu_nudge_controller_unittest.cc
index f193304f..3e859aae0 100644
--- a/ash/wm/multitask_menu_nudge_controller_unittest.cc
+++ b/ash/wm/multitask_menu_nudge_controller_unittest.cc
@@ -10,8 +10,11 @@
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_state.h"
+#include "ash/wm/wm_event.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
+#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h"
+#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h"
 #include "chromeos/ui/wm/features.h"
 
 namespace ash {
@@ -79,6 +82,31 @@
   EXPECT_TRUE(GetWidget());
 }
 
+// Tests that there is no crash after toggling fullscreen on and off. Regression
+// test for https://crbug.com/1341142.
+TEST_F(MultitaskMenuNudgeControllerTest, NoCrashAfterFullscreening) {
+  auto window = CreateAppWindow(gfx::Rect(300, 300));
+  ASSERT_FALSE(GetWidget());
+
+  // Turn of animations for immersive mode, so we don't have to wait for the top
+  // container to hide on fullscreen.
+  auto* immersive_controller = chromeos::ImmersiveFullscreenController::Get(
+      views::Widget::GetWidgetForNativeView(window.get()));
+  chromeos::ImmersiveFullscreenControllerTestApi(immersive_controller)
+      .SetupForTest();
+
+  const WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
+  WindowState::Get(window.get())->OnWMEvent(&event);
+
+  // Window needs to be immersive enabled, but not revealed for the bug to
+  // reproduce.
+  ASSERT_TRUE(immersive_controller->IsEnabled());
+  ASSERT_FALSE(immersive_controller->IsRevealed());
+
+  WindowState::Get(window.get())->OnWMEvent(&event);
+  EXPECT_FALSE(GetWidget());
+}
+
 TEST_F(MultitaskMenuNudgeControllerTest, NudgeTimeout) {
   auto window = CreateAppWindow(gfx::Rect(300, 300));
   WindowState::Get(window.get())->Maximize();
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index 0de11d740..cdee518 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -564,6 +564,71 @@
       void const volatile* ptr);
 };
 
+template <class Super>
+struct RawPtrCountingImplWrapperForTest : public Super {
+  template <typename T>
+  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
+    ++wrap_raw_ptr_cnt;
+    return Super::WrapRawPtr(ptr);
+  }
+
+  template <typename T>
+  static ALWAYS_INLINE void ReleaseWrappedPtr(T* ptr) {
+    ++release_wrapped_ptr_cnt;
+    Super::ReleaseWrappedPtr(ptr);
+  }
+
+  template <typename T>
+  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
+    ++get_for_dereference_cnt;
+    return Super::SafelyUnwrapPtrForDereference(wrapped_ptr);
+  }
+
+  template <typename T>
+  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
+    ++get_for_extraction_cnt;
+    return Super::SafelyUnwrapPtrForExtraction(wrapped_ptr);
+  }
+
+  template <typename T>
+  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
+    ++get_for_comparison_cnt;
+    return Super::UnsafelyUnwrapPtrForComparison(wrapped_ptr);
+  }
+
+  static ALWAYS_INLINE void IncrementSwapCountForTest() {
+    ++wrapped_ptr_swap_cnt;
+  }
+
+  static ALWAYS_INLINE void IncrementLessCountForTest() {
+    ++wrapped_ptr_less_cnt;
+  }
+
+  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {
+    ++pointer_to_member_operator_cnt;
+  }
+
+  static void ClearCounters() {
+    wrap_raw_ptr_cnt = 0;
+    release_wrapped_ptr_cnt = 0;
+    get_for_dereference_cnt = 0;
+    get_for_extraction_cnt = 0;
+    get_for_comparison_cnt = 0;
+    wrapped_ptr_swap_cnt = 0;
+    wrapped_ptr_less_cnt = 0;
+    pointer_to_member_operator_cnt = 0;
+  }
+
+  static inline int wrap_raw_ptr_cnt = INT_MIN;
+  static inline int release_wrapped_ptr_cnt = INT_MIN;
+  static inline int get_for_dereference_cnt = INT_MIN;
+  static inline int get_for_extraction_cnt = INT_MIN;
+  static inline int get_for_comparison_cnt = INT_MIN;
+  static inline int wrapped_ptr_swap_cnt = INT_MIN;
+  static inline int wrapped_ptr_less_cnt = INT_MIN;
+  static inline int pointer_to_member_operator_cnt = INT_MIN;
+};
+
 }  // namespace internal
 
 namespace raw_ptr_traits {
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc
index bb62dede..535d784 100644
--- a/base/memory/raw_ptr_unittest.cc
+++ b/base/memory/raw_ptr_unittest.cc
@@ -83,80 +83,8 @@
 // this namespace calls the correct functions from this namespace.
 namespace {
 
-#if BUILDFLAG(USE_BACKUP_REF_PTR)
-using CountingSuperClass =
-    base::internal::BackupRefPtrImpl</*AllowDangling=*/false>;
-#elif defined(PA_USE_MTE_CHECKED_PTR_WITH_64_BITS_POINTERS)
-using CountingSuperClass = base::internal::MTECheckedPtrImpl<
-    base::internal::MTECheckedPtrImplPartitionAllocSupport>;
-#else
-using CountingSuperClass = base::internal::RawPtrNoOpImpl;
-#endif
-struct RawPtrCountingImpl : public CountingSuperClass {
-  using Super = CountingSuperClass;
-
-  template <typename T>
-  static ALWAYS_INLINE T* WrapRawPtr(T* ptr) {
-    ++wrap_raw_ptr_cnt;
-    return Super::WrapRawPtr(ptr);
-  }
-
-  template <typename T>
-  static ALWAYS_INLINE void ReleaseWrappedPtr(T* ptr) {
-    ++release_wrapped_ptr_cnt;
-    Super::ReleaseWrappedPtr(ptr);
-  }
-
-  template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForDereference(T* wrapped_ptr) {
-    ++get_for_dereference_cnt;
-    return Super::SafelyUnwrapPtrForDereference(wrapped_ptr);
-  }
-
-  template <typename T>
-  static ALWAYS_INLINE T* SafelyUnwrapPtrForExtraction(T* wrapped_ptr) {
-    ++get_for_extraction_cnt;
-    return Super::SafelyUnwrapPtrForExtraction(wrapped_ptr);
-  }
-
-  template <typename T>
-  static ALWAYS_INLINE T* UnsafelyUnwrapPtrForComparison(T* wrapped_ptr) {
-    ++get_for_comparison_cnt;
-    return Super::UnsafelyUnwrapPtrForComparison(wrapped_ptr);
-  }
-
-  static ALWAYS_INLINE void IncrementSwapCountForTest() {
-    ++wrapped_ptr_swap_cnt;
-  }
-
-  static ALWAYS_INLINE void IncrementLessCountForTest() {
-    ++wrapped_ptr_less_cnt;
-  }
-
-  static ALWAYS_INLINE void IncrementPointerToMemberOperatorCountForTest() {
-    ++pointer_to_member_operator_cnt;
-  }
-
-  static void ClearCounters() {
-    wrap_raw_ptr_cnt = 0;
-    release_wrapped_ptr_cnt = 0;
-    get_for_dereference_cnt = 0;
-    get_for_extraction_cnt = 0;
-    get_for_comparison_cnt = 0;
-    wrapped_ptr_swap_cnt = 0;
-    wrapped_ptr_less_cnt = 0;
-    pointer_to_member_operator_cnt = 0;
-  }
-
-  static inline int wrap_raw_ptr_cnt = INT_MIN;
-  static inline int release_wrapped_ptr_cnt = INT_MIN;
-  static inline int get_for_dereference_cnt = INT_MIN;
-  static inline int get_for_extraction_cnt = INT_MIN;
-  static inline int get_for_comparison_cnt = INT_MIN;
-  static inline int wrapped_ptr_swap_cnt = INT_MIN;
-  static inline int wrapped_ptr_less_cnt = INT_MIN;
-  static inline int pointer_to_member_operator_cnt = INT_MIN;
-};
+using RawPtrCountingImpl =
+    base::internal::RawPtrCountingImplWrapperForTest<base::DefaultRawPtrImpl>;
 
 template <typename T>
 using CountingRawPtr = raw_ptr<T, RawPtrCountingImpl>;
diff --git a/base/memory/raw_ref.h b/base/memory/raw_ref.h
index 2ab69dd..fe231119 100644
--- a/base/memory/raw_ref.h
+++ b/base/memory/raw_ref.h
@@ -282,42 +282,51 @@
 
 // Override so set/map lookups do not create extra raw_ref. This also
 // allows C++ references to be used for lookup.
-template <typename T, typename I>
-struct less<raw_ref<T, I>> {
+template <typename T, typename Impl>
+struct less<raw_ref<T, Impl>> {
   using is_transparent = void;
 
-  bool operator()(const raw_ref<T, I>& lhs, const raw_ref<T, I>& rhs) const {
+  bool operator()(const raw_ref<T, Impl>& lhs,
+                  const raw_ref<T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const raw_ref<const T, I>& lhs,
-                  const raw_ref<const T, I>& rhs) const {
+  bool operator()(const raw_ref<const T, Impl>& lhs,
+                  const raw_ref<const T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const raw_ref<T, I>& lhs,
-                  const raw_ref<const T, I>& rhs) const {
+  bool operator()(const raw_ref<T, Impl>& lhs,
+                  const raw_ref<const T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const raw_ref<const T, I>& lhs,
-                  const raw_ref<T, I>& rhs) const {
+  bool operator()(const raw_ref<const T, Impl>& lhs,
+                  const raw_ref<T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const T& lhs, const raw_ref<const T, I>& rhs) const {
+  bool operator()(const T& lhs, const raw_ref<const T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const T& lhs, const raw_ref<T, I>& rhs) const {
+  bool operator()(const T& lhs, const raw_ref<T, Impl>& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const raw_ref<const T, I>& lhs, const T& rhs) const {
+  bool operator()(const raw_ref<const T, Impl>& lhs, const T& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 
-  bool operator()(const raw_ref<T, I>& lhs, const T& rhs) const {
+  bool operator()(const raw_ref<T, Impl>& lhs, const T& rhs) const {
+    Impl::IncrementLessCountForTest();
     return lhs < rhs;
   }
 };
diff --git a/base/memory/raw_ref_unittest.cc b/base/memory/raw_ref_unittest.cc
index 9b264a78..29faca3 100644
--- a/base/memory/raw_ref_unittest.cc
+++ b/base/memory/raw_ref_unittest.cc
@@ -711,67 +711,93 @@
   EXPECT_EQ(&*r, &i);
 }
 
+using RawPtrCountingImpl =
+    base::internal::RawPtrCountingImplWrapperForTest<base::DefaultRawPtrImpl>;
+
+template <typename T>
+using CountingRawRef = raw_ref<T, RawPtrCountingImpl>;
+
 TEST(RawRef, StdLess) {
   int i[] = {1, 1};
   {
-    auto r1 = raw_ref<int>(i[0]);
-    auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, r2));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, r1));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<int>(i[0]);
+    auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    const auto r1 = raw_ref<int>(i[0]);
-    const auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, r2));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, r1));
+    RawPtrCountingImpl::ClearCounters();
+    const auto r1 = CountingRawRef<int>(i[0]);
+    const auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<const int>(i[0]);
-    auto r2 = raw_ref<const int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, r2));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, r1));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<const int>(i[0]);
+    auto r2 = CountingRawRef<const int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<const int>(i[0]);
-    auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, r2));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, r1));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<const int>(i[0]);
+    auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<int>(i[0]);
-    auto r2 = raw_ref<const int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, r2));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, r1));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<int>(i[0]);
+    auto r2 = CountingRawRef<const int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<int>(i[0]);
-    auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, i[1]));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, i[0]));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<int>(i[0]);
+    auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    const auto r1 = raw_ref<int>(i[0]);
-    const auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, i[1]));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, i[0]));
+    RawPtrCountingImpl::ClearCounters();
+    const auto r1 = CountingRawRef<int>(i[0]);
+    const auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<const int>(i[0]);
-    auto r2 = raw_ref<const int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, i[1]));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, i[0]));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<const int>(i[0]);
+    auto r2 = CountingRawRef<const int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<const int>(i[0]);
-    auto r2 = raw_ref<int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, i[1]));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, i[0]));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<const int>(i[0]);
+    auto r2 = CountingRawRef<int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
   {
-    auto r1 = raw_ref<int>(i[0]);
-    auto r2 = raw_ref<const int>(i[1]);
-    EXPECT_TRUE(std::less<raw_ref<int>>()(r1, i[1]));
-    EXPECT_FALSE(std::less<raw_ref<int>>()(r2, i[0]));
+    RawPtrCountingImpl::ClearCounters();
+    auto r1 = CountingRawRef<int>(i[0]);
+    auto r2 = CountingRawRef<const int>(i[1]);
+    EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
+    EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
+    EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
   }
 }
 
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 174e2a5..60bc28f 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -395,6 +395,10 @@
   return c >= '0' && c <= '9';
 }
 template <typename Char>
+inline bool IsAsciiAlphaNumeric(Char c) {
+  return IsAsciiAlpha(c) || IsAsciiDigit(c);
+}
+template <typename Char>
 inline bool IsAsciiPrintable(Char c) {
   return c >= ' ' && c <= '~';
 }
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index b9a75572..378490b 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220707.2.1
+8.20220708.0.1
diff --git a/chrome/VERSION b/chrome/VERSION
index 8e5a57f..c472a2c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=105
 MINOR=0
-BUILD=5167
+BUILD=5168
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index f7f7780..0c1a809 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1049,6 +1049,7 @@
     "//chrome/browser/safety_check/android:junit",
     "//chrome/browser/search_engines/android:java",
     "//chrome/browser/search_resumption:junit",
+    "//chrome/browser/segmentation_platform:factory_java",
     "//chrome/browser/share:java",
     "//chrome/browser/signin/services/android:java",
     "//chrome/browser/signin/services/android:junit",
@@ -1163,6 +1164,7 @@
     "//components/search_engines/android:java",
     "//components/security_state/content/android:java",
     "//components/security_state/core:security_state_enums_java",
+    "//components/segmentation_platform/public:public_java",
     "//components/signin/core/browser:signin_enums_java",
     "//components/signin/public/android:java",
     "//components/signin/public/android:signin_java_test_support",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index 46353bfc..ad8cfb8 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -169,6 +169,7 @@
   "junit/src/org/chromium/chrome/browser/notifications/NotificationTriggerBackgroundTaskTest.java",
   "junit/src/org/chromium/chrome/browser/notifications/NotificationTriggerSchedulerTest.java",
   "junit/src/org/chromium/chrome/browser/notifications/WebPlatformNotificationMetricsTest.java",
+  "junit/src/org/chromium/chrome/browser/ntp/FeedPositionUtilUnitTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/ClientIdTest.java",
   "junit/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTaskTest.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/FeedPositionUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/FeedPositionUtils.java
index d96db100..e14b467 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/FeedPositionUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/FeedPositionUtils.java
@@ -4,28 +4,127 @@
 
 package org.chromium.chrome.browser.ntp;
 
+import androidx.annotation.IntDef;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.segmentation_platform.SegmentationPlatformServiceFactory;
+import org.chromium.components.segmentation_platform.SegmentSelectionResult;
+import org.chromium.components.segmentation_platform.SegmentationPlatformService;
+import org.chromium.components.segmentation_platform.proto.SegmentationProto.SegmentId;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * A class to handle the state of flags for Feed position experiment.
  */
 public class FeedPositionUtils {
+    // The key is used to decide whether the user likes to use Feed. Should be consistent with
+    // |kFeedUserSegmentationKey| in config.h in components/segmentation_platform/.
+    public static final String FEED_USER_SEGMENT_KEY = "feed_user_segment";
+    public static final String FEED_ACTIVE_TARGETING = "feed_active_targeting";
     public static final String PUSH_DOWN_FEED_SMALL = "push_down_feed_small";
     public static final String PUSH_DOWN_FEED_LARGE = "push_down_feed_large";
     public static final String PULL_UP_FEED = "pull_up_feed";
 
+    // Constants with FeedPositionSegmentationResult in enums.xml.
+    // These values are persisted to logs. Entries should not be renumbered and
+    // numeric values should never be reused.
+    @IntDef({FeedPositionSegmentationResult.UNINITIALIZED,
+            FeedPositionSegmentationResult.IS_FEED_ACTIVE_USER,
+            FeedPositionSegmentationResult.IS_NON_FEED_ACTIVE_USER,
+            FeedPositionSegmentationResult.NUM_ENTRIES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FeedPositionSegmentationResult {
+        int UNINITIALIZED = 0;
+        int IS_FEED_ACTIVE_USER = 1;
+        int IS_NON_FEED_ACTIVE_USER = 2;
+        int NUM_ENTRIES = 3;
+    }
+
+    /**
+     * Returns whether the pushing down (small) Feed experiment is enabled.
+     */
     public static boolean isFeedPushDownSmallEnabled() {
         return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.FEED_POSITION_ANDROID, PUSH_DOWN_FEED_SMALL, false);
+                       ChromeFeatureList.FEED_POSITION_ANDROID, PUSH_DOWN_FEED_SMALL, false)
+                && getBehaviourResultFromSegmentation();
     }
 
+    /**
+     * Returns whether the pushing down (large) Feed experiment is enabled.
+     */
     public static boolean isFeedPushDownLargeEnabled() {
         return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.FEED_POSITION_ANDROID, PUSH_DOWN_FEED_LARGE, false);
+                       ChromeFeatureList.FEED_POSITION_ANDROID, PUSH_DOWN_FEED_LARGE, false)
+                && getBehaviourResultFromSegmentation();
     }
 
+    /**
+     * Returns whether the pulling up Feed experiment is enabled.
+     */
     public static boolean isFeedPullUpEnabled() {
         return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                ChromeFeatureList.FEED_POSITION_ANDROID, PULL_UP_FEED, false);
+                       ChromeFeatureList.FEED_POSITION_ANDROID, PULL_UP_FEED, false)
+                && getBehaviourResultFromSegmentation();
+    }
+
+    /**
+     * Returns the string for whether we should target to Feed active users or non-Feed users:
+     * 1. "active" means targeting to Feed active users.
+     * 2. "non-active" means targeting to Non-Feed active users.
+     * 3. Other string (including empty string) is for no targeting.
+     */
+    @VisibleForTesting
+    static String getTargetFeedOrNonFeedUsersParam() {
+        return ChromeFeatureList.getFieldTrialParamByFeature(
+                ChromeFeatureList.FEED_POSITION_ANDROID, FEED_ACTIVE_TARGETING);
+    }
+
+    /**
+     * Called to check whether feed position should be enabled based on segmentation model result.
+     * Check whether we should target Feed active users, if not, return true; if so, check whether
+     * the user is a Feed/non-Feed active users accordingly.
+     */
+    private static boolean getBehaviourResultFromSegmentation() {
+        String targetFeedOrNonFeedUsersParam = getTargetFeedOrNonFeedUsersParam();
+        if (targetFeedOrNonFeedUsersParam == null) return true;
+
+        @FeedPositionSegmentationResult
+        int resultEnum = FeedPositionUtils.getSegmentationResult();
+        RecordHistogram.recordEnumeratedHistogram("NewTabPage.FeedPositionSegmentationResult",
+                resultEnum, FeedPositionSegmentationResult.NUM_ENTRIES);
+        switch (targetFeedOrNonFeedUsersParam) {
+            case "active":
+                return resultEnum == FeedPositionSegmentationResult.IS_FEED_ACTIVE_USER;
+            case "non-active":
+                return resultEnum == FeedPositionSegmentationResult.IS_NON_FEED_ACTIVE_USER;
+        }
+        return true;
+    }
+
+    /**
+     * Called to get segment selection result from segmentation platform service.
+     * @return The segmentation result.
+     */
+    private static @FeedPositionSegmentationResult int getSegmentationResult() {
+        @FeedPositionSegmentationResult
+        int resultEnum;
+        SegmentationPlatformService segmentationPlatformService =
+                SegmentationPlatformServiceFactory.getForProfile(
+                        Profile.getLastUsedRegularProfile());
+        SegmentSelectionResult result =
+                segmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY);
+        if (!result.isReady) {
+            resultEnum = FeedPositionSegmentationResult.UNINITIALIZED;
+        } else if (result.selectedSegment == SegmentId.OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER) {
+            resultEnum = FeedPositionSegmentationResult.IS_FEED_ACTIVE_USER;
+        } else {
+            resultEnum = FeedPositionSegmentationResult.IS_NON_FEED_ACTIVE_USER;
+        }
+        return resultEnum;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
index f9aa769..546c57bc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -937,8 +937,12 @@
 
     // TODO(crbug.com/1329288): Remove this method when the Feed position experiment is cleaned up.
     private int getGridMvtTopMargin() {
-        int resourcesId = !shouldShowLogo() ? R.dimen.tile_grid_layout_no_logo_top_margin
-                                            : R.dimen.tile_grid_layout_top_margin;
+        if (!shouldShowLogo()) {
+            return getResources().getDimensionPixelOffset(
+                    R.dimen.tile_grid_layout_no_logo_top_margin);
+        }
+
+        int resourcesId = R.dimen.tile_grid_layout_top_margin;
 
         if (FeedPositionUtils.isFeedPushDownLargeEnabled()) {
             resourcesId = R.dimen.tile_grid_layout_top_margin_push_down_large;
@@ -955,6 +959,8 @@
     private int getGridMvtBottomMargin() {
         int resourcesId = R.dimen.tile_grid_layout_bottom_margin;
 
+        if (!shouldShowLogo()) return getResources().getDimensionPixelOffset(resourcesId);
+
         if (FeedPositionUtils.isFeedPushDownLargeEnabled()) {
             resourcesId = R.dimen.tile_grid_layout_bottom_margin_push_down_large;
         } else if (FeedPositionUtils.isFeedPushDownSmallEnabled()) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/DEPS b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/DEPS
new file mode 100644
index 0000000..e87bac6
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentSelectionResult.java",
+  "+components/segmentation_platform/public/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformService.java",
+]
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/FeedPositionUtilUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/FeedPositionUtilUnitTest.java
new file mode 100644
index 0000000..7125c34
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/FeedPositionUtilUnitTest.java
@@ -0,0 +1,128 @@
+// 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.ntp;
+
+import static org.mockito.Mockito.when;
+
+import static org.chromium.chrome.browser.ntp.FeedPositionUtils.FEED_USER_SEGMENT_KEY;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.FeatureList;
+import org.chromium.base.FeatureList.TestValues;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.segmentation_platform.SegmentationPlatformServiceFactory;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.segmentation_platform.SegmentSelectionResult;
+import org.chromium.components.segmentation_platform.SegmentationPlatformService;
+import org.chromium.components.segmentation_platform.proto.SegmentationProto.SegmentId;
+
+/** Unit tests for {@link FeedPositionUtils} class. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class FeedPositionUtilUnitTest {
+    @Rule
+    public TestRule mProcessor = new Features.JUnitProcessor();
+
+    private final TestValues mTestValues = new TestValues();
+
+    @Mock
+    Profile mProfile;
+    @Mock
+    SegmentationPlatformService mSegmentationPlatformService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        LibraryLoader.getInstance().setLibrariesLoadedForNativeTests();
+        Assert.assertTrue(LibraryLoader.getInstance().isInitialized());
+
+        Profile.setLastUsedProfileForTesting(mProfile);
+        SegmentationPlatformServiceFactory.setForTests(mSegmentationPlatformService);
+        when(mSegmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY))
+                .thenReturn(new SegmentSelectionResult(false, null));
+    }
+
+    @After
+    public void tearDown() {
+        FeatureList.setTestValues(null);
+    }
+
+    @Test
+    @SmallTest
+    public void testIsFeedPushDownSmallEnabled() {
+        setFeedPositionFlags(FeedPositionUtils.PUSH_DOWN_FEED_SMALL, "");
+        Assert.assertTrue(FeedPositionUtils.isFeedPushDownSmallEnabled());
+
+        setFeedPositionFlags(FeedPositionUtils.PUSH_DOWN_FEED_SMALL, "active");
+        Assert.assertFalse(FeedPositionUtils.isFeedPushDownSmallEnabled());
+
+        when(mSegmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY))
+                .thenReturn(new SegmentSelectionResult(
+                        true, SegmentId.OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER));
+        Assert.assertTrue(FeedPositionUtils.isFeedPushDownSmallEnabled());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsFeedPushDownLargeEnabled() {
+        setFeedPositionFlags(FeedPositionUtils.PUSH_DOWN_FEED_LARGE, "");
+        Assert.assertTrue(FeedPositionUtils.isFeedPushDownLargeEnabled());
+
+        setFeedPositionFlags(FeedPositionUtils.PUSH_DOWN_FEED_SMALL, "active");
+        Assert.assertFalse(FeedPositionUtils.isFeedPushDownLargeEnabled());
+
+        when(mSegmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY))
+                .thenReturn(new SegmentSelectionResult(
+                        true, SegmentId.OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER));
+        Assert.assertTrue(FeedPositionUtils.isFeedPushDownLargeEnabled());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsFeedPullUpEnabled() {
+        setFeedPositionFlags(FeedPositionUtils.PULL_UP_FEED, "");
+        Assert.assertTrue(FeedPositionUtils.isFeedPullUpEnabled());
+
+        setFeedPositionFlags(FeedPositionUtils.PULL_UP_FEED, "non-active");
+        Assert.assertFalse(FeedPositionUtils.isFeedPullUpEnabled());
+
+        when(mSegmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY))
+                .thenReturn(new SegmentSelectionResult(
+                        true, SegmentId.OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER));
+        Assert.assertFalse(FeedPositionUtils.isFeedPullUpEnabled());
+
+        when(mSegmentationPlatformService.getCachedSegmentResult(FEED_USER_SEGMENT_KEY))
+                .thenReturn(
+                        new SegmentSelectionResult(true, SegmentId.OPTIMIZATION_TARGET_UNKNOWN));
+        Assert.assertTrue(FeedPositionUtils.isFeedPullUpEnabled());
+    }
+
+    private void setFeedPositionFlags(
+            String feedPositionVariation, String targetFeedOrNonFeedUsersValue) {
+        mTestValues.addFieldTrialParamOverride(
+                ChromeFeatureList.FEED_POSITION_ANDROID, feedPositionVariation, "true");
+        mTestValues.addFieldTrialParamOverride(ChromeFeatureList.FEED_POSITION_ANDROID,
+                FeedPositionUtils.FEED_ACTIVE_TARGETING, targetFeedOrNonFeedUsersValue);
+        FeatureList.setTestValues(mTestValues);
+
+        Assert.assertEquals(targetFeedOrNonFeedUsersValue,
+                FeedPositionUtils.getTargetFeedOrNonFeedUsersParam());
+    }
+}
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 9d1e69a..2ead82e 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-105.0.5161.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-105.0.5165.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/vector_icons/autofill/webauthn_dialog_header.icon b/chrome/app/vector_icons/autofill/webauthn_dialog_header.icon
index 988e785..4b7454c 100644
--- a/chrome/app/vector_icons/autofill/webauthn_dialog_header.icon
+++ b/chrome/app/vector_icons/autofill/webauthn_dialog_header.icon
@@ -65,81 +65,32 @@
 ARC_TO, 41.14f, 41.14f, 0, 0, 0, 154.73f, 55.91f,
 NEW_PATH,
 PATH_COLOR_ARGB, 0xFF, 0x1A, 0x73, 0xE8,
-MOVE_TO, 142.03f, 69.83f,
-R_CUBIC_TO, -0.19f, 0, -0.39f, -0.05f, -0.56f, -0.14f,
-R_CUBIC_TO, -4.64f, -2.33f, -8.65f, -3.33f, -13.46f, -3.33f,
-R_CUBIC_TO, -4.79f, 0, -9.33f, 1.11f, -13.46f, 3.33f,
-R_ARC_TO, 1.25f, 1.25f, 0, 0, 1, -1.64f, -0.47f,
-R_ARC_TO, 1.18f, 1.18f, 0, 0, 1, 0.48f, -1.6f,
-R_CUBIC_TO, 4.5f, -2.38f, 9.43f, -3.61f, 14.62f, -3.61f,
-R_CUBIC_TO, 5.15f, 0, 9.65f, 1.11f, 14.58f, 3.59f,
-R_CUBIC_TO, 0.6f, 0.31f, 0.82f, 1.01f, 0.51f, 1.58f,
-R_CUBIC_TO, -0.22f, 0.43f, -0.63f, 0.66f, -1.06f, 0.66f,
+MOVE_TO, 115.96f, 76.75f,
+H_LINE_TO, 144.63f,
+V_LINE_TO, 73.17f,
+H_LINE_TO, 115.96f,
+CUBIC_TO, 113.99f, 73.17f, 112.38f, 74.78f, 112.38f, 76.75f,
+V_LINE_TO, 96.46f,
+H_LINE_TO, 108.79f,
+V_LINE_TO, 101.83f,
+H_LINE_TO, 128.5f,
+V_LINE_TO, 96.46f,
+H_LINE_TO, 115.96f,
+V_LINE_TO, 76.75f,
 CLOSE,
-R_MOVE_TO, -34.54f, 12.95f,
-R_CUBIC_TO, -0.24f, 0, -0.48f, -0.07f, -0.7f, -0.22f,
-R_ARC_TO, 1.24f, 1.24f, 0, 0, 1, -0.29f, -1.72f,
-R_CUBIC_TO, 2.39f, -3.43f, 5.43f, -6.13f, 9.05f, -8.02f,
-R_CUBIC_TO, 7.58f, -3.97f, 17.29f, -4, 24.89f, -0.02f,
-R_CUBIC_TO, 3.62f, 1.89f, 6.66f, 4.56f, 9.05f, 7.97f,
-R_CUBIC_TO, 0.39f, 0.54f, 0.27f, 1.33f, -0.29f, 1.72f,
-R_ARC_TO, 1.19f, 1.19f, 0, 0, 1, -1.69f, -0.29f,
-R_CUBIC_TO, -2.17f, -3.09f, -4.92f, -5.52f, -8.18f, -7.21f,
-R_CUBIC_TO, -6.93f, -3.6f, -15.79f, -3.6f, -22.69f, 0.02f,
-R_CUBIC_TO, -3.28f, 1.72f, -6.03f, 4.17f, -8.21f, 7.26f,
-R_CUBIC_TO, -0.19f, 0.34f, -0.56f, 0.52f, -0.94f, 0.52f,
+MOVE_TO, 144.63f, 80.33f,
+H_LINE_TO, 133.88f,
+CUBIC_TO, 132.89f, 80.33f, 132.08f, 81.14f, 132.08f, 82.13f,
+V_LINE_TO, 100.04f,
+CUBIC_TO, 132.08f, 101.03f, 132.89f, 101.83f, 133.88f, 101.83f,
+H_LINE_TO, 144.63f,
+CUBIC_TO, 145.61f, 101.83f, 146.42f, 101.03f, 146.42f, 100.04f,
+V_LINE_TO, 82.13f,
+CUBIC_TO, 146.42f, 81.14f, 145.61f, 80.33f, 144.63f, 80.33f,
 CLOSE,
-R_MOVE_TO, 14.77f, 29.14f,
-R_CUBIC_TO, -0.31f, 0, -0.62f, -0.12f, -0.84f, -0.36f,
-R_CUBIC_TO, -2.09f, -2.12f, -3.22f, -3.48f, -4.84f, -6.42f,
-R_CUBIC_TO, -1.66f, -2.99f, -2.53f, -6.63f, -2.53f, -10.55f,
-R_CUBIC_TO, 0, -7.22f, 6.11f, -13.1f, 13.62f, -13.1f,
-R_CUBIC_TO, 7.51f, 0, 13.62f, 5.88f, 13.62f, 13.1f,
-R_CUBIC_TO, 0, 0.68f, -0.53f, 1.22f, -1.2f, 1.22f,
-R_ARC_TO, 1.2f, 1.2f, 0, 0, 1, -1.2f, -1.22f,
-R_CUBIC_TO, 0, -5.88f, -5.03f, -10.67f, -11.21f, -10.67f,
-R_CUBIC_TO, -6.18f, 0, -11.21f, 4.79f, -11.21f, 10.67f,
-R_CUBIC_TO, 0, 3.5f, 0.77f, 6.73f, 2.24f, 9.36f,
-R_CUBIC_TO, 1.54f, 2.8f, 2.6f, 3.99f, 4.45f, 5.88f,
-R_CUBIC_TO, 0.46f, 0.49f, 0.46f, 1.24f, 0, 1.73f,
-R_ARC_TO, 1.31f, 1.31f, 0, 0, 1, -0.89f, 0.37f,
-CLOSE,
-R_MOVE_TO, 17.11f, -3.88f,
-R_CUBIC_TO, -2.82f, 0, -5.31f, -0.74f, -7.35f, -2.19f,
-R_CUBIC_TO, -3.53f, -2.49f, -5.64f, -6.53f, -5.64f, -10.82f,
-R_CUBIC_TO, 0, -0.69f, 0.52f, -1.23f, 1.19f, -1.23f,
-R_CUBIC_TO, 0.66f, 0, 1.19f, 0.54f, 1.19f, 1.23f,
-R_ARC_TO, 10.71f, 10.71f, 0, 0, 0, 4.6f, 8.77f,
-R_CUBIC_TO, 1.68f, 1.18f, 3.65f, 1.75f, 6.03f, 1.75f,
-R_CUBIC_TO, 0.57f, 0, 1.52f, -0.07f, 2.47f, -0.25f,
-R_CUBIC_TO, 0.64f, -0.12f, 1.26f, 0.32f, 1.38f, 1.01f,
-R_ARC_TO, 1.23f, 1.23f, 0, 0, 1, -0.97f, 1.43f,
-R_ARC_TO, 15.61f, 15.61f, 0, 0, 1, -2.87f, 0.3f,
-CLOSE,
-R_MOVE_TO, -4.35f, 4.53f,
-R_CUBIC_TO, -0.1f, 0, -0.22f, -0.02f, -0.31f, -0.05f,
-R_CUBIC_TO, -3.83f, -1.07f, -6.33f, -2.5f, -8.95f, -5.11f,
-R_CUBIC_TO, -3.37f, -3.38f, -5.22f, -7.88f, -5.22f, -12.69f,
-R_CUBIC_TO, 0, -3.94f, 3.32f, -7.15f, 7.41f, -7.15f,
-R_CUBIC_TO, 4.09f, 0, 7.41f, 3.21f, 7.41f, 7.15f,
-R_CUBIC_TO, 0, 2.6f, 2.24f, 4.72f, 5, 4.72f,
-R_CUBIC_TO, 2.77f, 0, 5.01f, -2.12f, 5.01f, -4.72f,
-R_CUBIC_TO, 0, -9.17f, -7.82f, -16.6f, -17.44f, -16.6f,
-R_CUBIC_TO, -6.83f, 0, -13.09f, 3.84f, -15.9f, 9.8f,
-R_CUBIC_TO, -0.94f, 1.97f, -1.42f, 4.28f, -1.42f, 6.81f,
-R_CUBIC_TO, 0, 1.9f, 0.17f, 4.89f, 1.61f, 8.78f,
-R_CUBIC_TO, 0.24f, 0.63f, -0.07f, 1.34f, -0.7f, 1.56f,
-R_ARC_TO, 1.19f, 1.19f, 0, 0, 1, -1.54f, -0.7f,
-R_CUBIC_TO, -1.18f, -3.18f, -1.76f, -6.34f, -1.76f, -9.63f,
-R_CUBIC_TO, 0, -2.92f, 0.55f, -5.57f, 1.64f, -7.88f,
-R_CUBIC_TO, 3.2f, -6.78f, 10.3f, -11.18f, 18.07f, -11.18f,
-R_CUBIC_TO, 10.95f, 0, 19.85f, 8.53f, 19.85f, 19.04f,
-R_CUBIC_TO, 0, 3.94f, -3.32f, 7.15f, -7.41f, 7.15f,
-R_CUBIC_TO, -4.09f, 0, -7.41f, -3.21f, -7.41f, -7.15f,
-R_CUBIC_TO, 0, -2.6f, -2.24f, -4.72f, -5, -4.72f,
-R_CUBIC_TO, -2.76f, 0, -5, 2.12f, -5, 4.72f,
-R_CUBIC_TO, 0, 4.16f, 1.59f, 8.05f, 4.5f, 10.97f,
-R_CUBIC_TO, 2.29f, 2.29f, 4.47f, 3.55f, 7.87f, 4.5f,
-R_CUBIC_TO, 0.65f, 0.17f, 1.01f, 0.85f, 0.84f, 1.48f,
-R_CUBIC_TO, -0.12f, 0.56f, -0.63f, 0.92f, -1.13f, 0.92f,
+MOVE_TO, 135.67f, 96.46f,
+H_LINE_TO, 142.83f,
+V_LINE_TO, 83.92f,
+H_LINE_TO, 135.67f,
+V_LINE_TO, 96.46f,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/autofill/webauthn_dialog_header_dark.icon b/chrome/app/vector_icons/autofill/webauthn_dialog_header_dark.icon
index db9ebc3..da3ff259 100644
--- a/chrome/app/vector_icons/autofill/webauthn_dialog_header_dark.icon
+++ b/chrome/app/vector_icons/autofill/webauthn_dialog_header_dark.icon
@@ -31,6 +31,15 @@
 ARC_TO, 16.09f, 16.09f, 0, 0, 1, 44.36f, 57,
 R_CUBIC_TO, 8.67f, 0, 15.76f, 6.87f, 16.13f, 15.44f,
 CLOSE,
+MOVE_TO, 60.49f, 72.44f,
+H_LINE_TO, 17,
+R_CUBIC_TO, 0.36f, -5.48f, 4.94f, -9.83f, 10.51f, -9.83f,
+R_CUBIC_TO, 1.18f, 0, 2.36f, 0.21f, 3.51f, 0.61f,
+R_LINE_TO, 0.47f, 0.17f,
+R_LINE_TO, 0.31f, -0.39f,
+ARC_TO, 16.09f, 16.09f, 0, 0, 1, 44.36f, 57,
+R_CUBIC_TO, 8.67f, 0, 15.76f, 6.87f, 16.13f, 15.44f,
+CLOSE,
 NEW_PATH,
 PATH_COLOR_ARGB, 0xFF, 0x41, 0x44, 0x47,
 CIRCLE, 128, 87, 37.058,
@@ -56,81 +65,32 @@
 ARC_TO, 41.14f, 41.14f, 0, 0, 0, 154.73f, 55.91f,
 NEW_PATH,
 PATH_COLOR_ARGB, 0xFF, 0x8A, 0xB4, 0xF8,
-MOVE_TO, 142.03f, 69.83f,
-R_CUBIC_TO, -0.19f, 0, -0.39f, -0.05f, -0.56f, -0.14f,
-R_CUBIC_TO, -4.64f, -2.33f, -8.65f, -3.33f, -13.46f, -3.33f,
-R_CUBIC_TO, -4.79f, 0, -9.33f, 1.11f, -13.46f, 3.33f,
-R_ARC_TO, 1.25f, 1.25f, 0, 0, 1, -1.64f, -0.47f,
-R_ARC_TO, 1.18f, 1.18f, 0, 0, 1, 0.48f, -1.6f,
-R_CUBIC_TO, 4.5f, -2.38f, 9.43f, -3.61f, 14.62f, -3.61f,
-R_CUBIC_TO, 5.15f, 0, 9.65f, 1.11f, 14.58f, 3.59f,
-R_CUBIC_TO, 0.6f, 0.31f, 0.82f, 1.01f, 0.51f, 1.58f,
-R_CUBIC_TO, -0.22f, 0.43f, -0.63f, 0.66f, -1.06f, 0.66f,
+MOVE_TO, 115.96f, 76.75f,
+H_LINE_TO, 144.63f,
+V_LINE_TO, 73.17f,
+H_LINE_TO, 115.96f,
+CUBIC_TO, 113.99f, 73.17f, 112.38f, 74.78f, 112.38f, 76.75f,
+V_LINE_TO, 96.46f,
+H_LINE_TO, 108.79f,
+V_LINE_TO, 101.83f,
+H_LINE_TO, 128.5f,
+V_LINE_TO, 96.46f,
+H_LINE_TO, 115.96f,
+V_LINE_TO, 76.75f,
 CLOSE,
-R_MOVE_TO, -34.54f, 12.95f,
-R_CUBIC_TO, -0.24f, 0, -0.48f, -0.07f, -0.7f, -0.22f,
-R_ARC_TO, 1.24f, 1.24f, 0, 0, 1, -0.29f, -1.72f,
-R_CUBIC_TO, 2.39f, -3.43f, 5.43f, -6.13f, 9.05f, -8.02f,
-R_CUBIC_TO, 7.58f, -3.97f, 17.29f, -4, 24.89f, -0.02f,
-R_CUBIC_TO, 3.62f, 1.89f, 6.66f, 4.56f, 9.05f, 7.97f,
-R_CUBIC_TO, 0.39f, 0.54f, 0.27f, 1.33f, -0.29f, 1.72f,
-R_ARC_TO, 1.19f, 1.19f, 0, 0, 1, -1.69f, -0.29f,
-R_CUBIC_TO, -2.17f, -3.09f, -4.92f, -5.52f, -8.18f, -7.21f,
-R_CUBIC_TO, -6.93f, -3.6f, -15.79f, -3.6f, -22.69f, 0.02f,
-R_CUBIC_TO, -3.28f, 1.72f, -6.03f, 4.17f, -8.21f, 7.26f,
-R_CUBIC_TO, -0.19f, 0.34f, -0.56f, 0.52f, -0.94f, 0.52f,
+MOVE_TO, 144.63f, 80.33f,
+H_LINE_TO, 133.88f,
+CUBIC_TO, 132.89f, 80.33f, 132.08f, 81.14f, 132.08f, 82.13f,
+V_LINE_TO, 100.04f,
+CUBIC_TO, 132.08f, 101.03f, 132.89f, 101.83f, 133.88f, 101.83f,
+H_LINE_TO, 144.63f,
+CUBIC_TO, 145.61f, 101.83f, 146.42f, 101.03f, 146.42f, 100.04f,
+V_LINE_TO, 82.13f,
+CUBIC_TO, 146.42f, 81.14f, 145.61f, 80.33f, 144.63f, 80.33f,
 CLOSE,
-R_MOVE_TO, 14.77f, 29.14f,
-R_CUBIC_TO, -0.31f, 0, -0.62f, -0.12f, -0.84f, -0.36f,
-R_CUBIC_TO, -2.09f, -2.12f, -3.22f, -3.48f, -4.84f, -6.42f,
-R_CUBIC_TO, -1.66f, -2.99f, -2.53f, -6.63f, -2.53f, -10.55f,
-R_CUBIC_TO, 0, -7.22f, 6.11f, -13.1f, 13.62f, -13.1f,
-R_CUBIC_TO, 7.51f, 0, 13.62f, 5.88f, 13.62f, 13.1f,
-R_CUBIC_TO, 0, 0.68f, -0.53f, 1.22f, -1.2f, 1.22f,
-R_ARC_TO, 1.2f, 1.2f, 0, 0, 1, -1.2f, -1.22f,
-R_CUBIC_TO, 0, -5.88f, -5.03f, -10.67f, -11.21f, -10.67f,
-R_CUBIC_TO, -6.18f, 0, -11.21f, 4.79f, -11.21f, 10.67f,
-R_CUBIC_TO, 0, 3.5f, 0.77f, 6.73f, 2.24f, 9.36f,
-R_CUBIC_TO, 1.54f, 2.8f, 2.6f, 3.99f, 4.45f, 5.88f,
-R_CUBIC_TO, 0.46f, 0.49f, 0.46f, 1.24f, 0, 1.73f,
-R_ARC_TO, 1.31f, 1.31f, 0, 0, 1, -0.89f, 0.37f,
-CLOSE,
-R_MOVE_TO, 17.11f, -3.88f,
-R_CUBIC_TO, -2.82f, 0, -5.31f, -0.74f, -7.35f, -2.19f,
-R_CUBIC_TO, -3.53f, -2.49f, -5.64f, -6.53f, -5.64f, -10.82f,
-R_CUBIC_TO, 0, -0.69f, 0.52f, -1.23f, 1.19f, -1.23f,
-R_CUBIC_TO, 0.66f, 0, 1.19f, 0.54f, 1.19f, 1.23f,
-R_ARC_TO, 10.71f, 10.71f, 0, 0, 0, 4.6f, 8.77f,
-R_CUBIC_TO, 1.68f, 1.18f, 3.65f, 1.75f, 6.03f, 1.75f,
-R_CUBIC_TO, 0.57f, 0, 1.52f, -0.07f, 2.47f, -0.25f,
-R_CUBIC_TO, 0.64f, -0.12f, 1.26f, 0.32f, 1.38f, 1.01f,
-R_ARC_TO, 1.23f, 1.23f, 0, 0, 1, -0.97f, 1.43f,
-R_ARC_TO, 15.61f, 15.61f, 0, 0, 1, -2.87f, 0.3f,
-CLOSE,
-R_MOVE_TO, -4.35f, 4.53f,
-R_CUBIC_TO, -0.1f, 0, -0.22f, -0.02f, -0.31f, -0.05f,
-R_CUBIC_TO, -3.83f, -1.07f, -6.33f, -2.5f, -8.95f, -5.11f,
-R_CUBIC_TO, -3.37f, -3.38f, -5.22f, -7.88f, -5.22f, -12.69f,
-R_CUBIC_TO, 0, -3.94f, 3.32f, -7.15f, 7.41f, -7.15f,
-R_CUBIC_TO, 4.09f, 0, 7.41f, 3.21f, 7.41f, 7.15f,
-R_CUBIC_TO, 0, 2.6f, 2.24f, 4.72f, 5, 4.72f,
-R_CUBIC_TO, 2.77f, 0, 5.01f, -2.12f, 5.01f, -4.72f,
-R_CUBIC_TO, 0, -9.17f, -7.82f, -16.6f, -17.44f, -16.6f,
-R_CUBIC_TO, -6.83f, 0, -13.09f, 3.84f, -15.9f, 9.8f,
-R_CUBIC_TO, -0.94f, 1.97f, -1.42f, 4.28f, -1.42f, 6.81f,
-R_CUBIC_TO, 0, 1.9f, 0.17f, 4.89f, 1.61f, 8.78f,
-R_CUBIC_TO, 0.24f, 0.63f, -0.07f, 1.34f, -0.7f, 1.56f,
-R_ARC_TO, 1.19f, 1.19f, 0, 0, 1, -1.54f, -0.7f,
-R_CUBIC_TO, -1.18f, -3.18f, -1.76f, -6.34f, -1.76f, -9.63f,
-R_CUBIC_TO, 0, -2.92f, 0.55f, -5.57f, 1.64f, -7.88f,
-R_CUBIC_TO, 3.2f, -6.78f, 10.3f, -11.18f, 18.07f, -11.18f,
-R_CUBIC_TO, 10.95f, 0, 19.85f, 8.53f, 19.85f, 19.04f,
-R_CUBIC_TO, 0, 3.94f, -3.32f, 7.15f, -7.41f, 7.15f,
-R_CUBIC_TO, -4.09f, 0, -7.41f, -3.21f, -7.41f, -7.15f,
-R_CUBIC_TO, 0, -2.6f, -2.24f, -4.72f, -5, -4.72f,
-R_CUBIC_TO, -2.76f, 0, -5, 2.12f, -5, 4.72f,
-R_CUBIC_TO, 0, 4.16f, 1.59f, 8.05f, 4.5f, 10.97f,
-R_CUBIC_TO, 2.29f, 2.29f, 4.47f, 3.55f, 7.87f, 4.5f,
-R_CUBIC_TO, 0.65f, 0.17f, 1.01f, 0.85f, 0.84f, 1.48f,
-R_CUBIC_TO, -0.12f, 0.56f, -0.63f, 0.92f, -1.13f, 0.92f,
+MOVE_TO, 135.67f, 96.46f,
+H_LINE_TO, 142.83f,
+V_LINE_TO, 83.92f,
+H_LINE_TO, 135.67f,
+V_LINE_TO, 96.46f,
 CLOSE
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 44ffe94..4de0217 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5140,6 +5140,7 @@
       "//chrome/services/speech:lib",
       "//chromeos/ash/components/assistant:buildflags",
       "//chromeos/ash/components/dbus/concierge",
+      "//chromeos/ash/components/dbus/image_loader",
       "//chromeos/ash/components/dbus/session_manager",
       "//chromeos/ash/components/dbus/update_engine",
       "//chromeos/ash/components/dbus/userdataauth:userdataauth",
@@ -5163,7 +5164,6 @@
       "//chromeos/dbus/attestation:attestation_proto",
       "//chromeos/dbus/cros_disks",
       "//chromeos/dbus/cryptohome",
-      "//chromeos/dbus/image_loader",
       "//chromeos/dbus/power",
       "//chromeos/dbus/tpm_manager",
       "//chromeos/dbus/tpm_manager:tpm_manager_proto",
@@ -5203,7 +5203,6 @@
       "//components/webapk:proto",
       "//device/vr/public/mojom:isolated_xr_service",
       "//remoting/host/chromeos:features",
-      "//third_party/smhasher:murmurhash2",
       "//ui/chromeos",
       "//ui/events/ozone",
       "//ui/ozone",
@@ -5561,6 +5560,8 @@
       "apps/app_service/media_requests.cc",
       "apps/app_service/media_requests.h",
       "apps/app_service/menu_item_constants.h",
+      "apps/app_service/webapk/webapk_utils.cc",
+      "apps/app_service/webapk/webapk_utils.h",
       "apps/intent_helper/chromeos_intent_picker_helpers.cc",
       "apps/intent_helper/chromeos_intent_picker_helpers.h",
       "apps/intent_helper/common_apps_navigation_throttle.cc",
@@ -5693,6 +5694,8 @@
       "//components/arc/common:arc_intent_helper_constants",
       "//components/pref_registry:pref_registry",
       "//components/prefs:prefs",
+      "//components/webapk:proto",
+      "//third_party/smhasher:murmurhash2",
       "//ui/wm/public",
     ]
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0dd2bca..4bf78ef1 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1990,6 +1990,26 @@
 const FeatureEntry::FeatureParam kFeedPositionAndroid_pull_up_feed[] = {
     {"pull_up_feed", "true"}};
 
+const FeatureEntry::FeatureParam
+    kFeedPositionAndroid_push_down_feed_large_target_feed_active[] = {
+        {"push_down_feed_large", "true"},
+        {"feed_active_targeting", "active"}};
+
+const FeatureEntry::FeatureParam
+    kFeedPositionAndroid_push_down_feed_large_target_non_feed_active[] = {
+        {"push_down_feed_large", "true"},
+        {"feed_active_targeting", "non-active"}};
+
+const FeatureEntry::FeatureParam
+    kFeedPositionAndroid_pull_up_feed_target_feed_active[] = {
+        {"pull_up_feed", "true"},
+        {"feed_active_targeting", "active"}};
+
+const FeatureEntry::FeatureParam
+    kFeedPositionAndroid_pull_up_feed_target_non_feed_active[] = {
+        {"pull_up_feed", "true"},
+        {"feed_active_targeting", "non-active"}};
+
 const FeatureEntry::FeatureVariation kFeedPositionAndroidVariations[] = {
     {"Push down Feed (small)", kFeedPositionAndroid_push_down_feed_small,
      std::size(kFeedPositionAndroid_push_down_feed_small), nullptr},
@@ -1997,6 +2017,23 @@
      std::size(kFeedPositionAndroid_push_down_feed_large), nullptr},
     {"Pull up Feed", kFeedPositionAndroid_pull_up_feed,
      std::size(kFeedPositionAndroid_pull_up_feed), nullptr},
+    {"Push down Feed (large) with targeting Feed active users",
+     kFeedPositionAndroid_push_down_feed_large_target_feed_active,
+     std::size(kFeedPositionAndroid_push_down_feed_large_target_feed_active),
+     nullptr},
+    {"Push down Feed (large) with targeting non-Feed active users",
+     kFeedPositionAndroid_push_down_feed_large_target_non_feed_active,
+     std::size(
+         kFeedPositionAndroid_push_down_feed_large_target_non_feed_active),
+     nullptr},
+    {"Pull up Feed with targeting Feed active users",
+     kFeedPositionAndroid_pull_up_feed_target_feed_active,
+     std::size(kFeedPositionAndroid_pull_up_feed_target_feed_active), nullptr},
+    {"Pull up Feed with targeting non-Feed active users",
+     kFeedPositionAndroid_pull_up_feed_target_non_feed_active,
+     std::size(kFeedPositionAndroid_pull_up_feed_target_non_feed_active),
+     nullptr},
+
 };
 
 const FeatureEntry::FeatureParam kSearchResumption_use_new_service[] = {
@@ -7476,13 +7513,6 @@
      flag_descriptions::kChromeLabsDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kChromeLabs)},
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    {"launcher-search-normalization",
-     flag_descriptions::kEnableLauncherSearchNormalizationName,
-     flag_descriptions::kEnableLauncherSearchNormalizationDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(app_list_features::kEnableLauncherSearchNormalization)},
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
     {"enable-first-party-sets", flag_descriptions::kEnableFirstPartySetsName,
      flag_descriptions::kEnableFirstPartySetsDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kFirstPartySets)},
@@ -7835,11 +7865,13 @@
      FEATURE_VALUE_TYPE(chromeos::features::kEnableInputInDiagnosticsApp)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
     {"use-passthrough-command-decoder",
      flag_descriptions::kUsePassthroughCommandDecoderName,
      flag_descriptions::kUsePassthroughCommandDecoderDescription,
      kOsMac | kOsLinux | kOsLacros | kOsCrOS | kOsAndroid | kOsFuchsia,
      FEATURE_VALUE_TYPE(features::kDefaultPassthroughCommandDecoder)},
+#endif  // !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"focus-follows-cursor", flag_descriptions::kFocusFollowsCursorName,
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc
index 1d427c7..22914bd 100644
--- a/chrome/browser/apps/app_service/intent_util.cc
+++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -1037,9 +1037,19 @@
         mime_type, apps::PatternMatchType::kMimeType));
   }
   if (!mime_type_condition_values.empty()) {
-    auto mime_type_condition = std::make_unique<apps::Condition>(
-        apps::ConditionType::kMimeType, std::move(mime_type_condition_values));
-    intent_filter->conditions.push_back(std::move(mime_type_condition));
+    // For ARC view file intents, save the mime type conditions under kFile
+    // instead of kMimeType to maintain consistency with view file intents of
+    // other app types.
+    if (has_view_action) {
+      auto file_type_condition = std::make_unique<apps::Condition>(
+          apps::ConditionType::kFile, std::move(mime_type_condition_values));
+      intent_filter->conditions.push_back(std::move(file_type_condition));
+    } else {
+      auto mime_type_condition = std::make_unique<apps::Condition>(
+          apps::ConditionType::kMimeType,
+          std::move(mime_type_condition_values));
+      intent_filter->conditions.push_back(std::move(mime_type_condition));
+    }
   }
   if (!arc_intent_filter.activity_name().empty()) {
     intent_filter->activity_name = arc_intent_filter.activity_name();
@@ -1138,10 +1148,20 @@
         mime_type, apps::mojom::PatternMatchType::kMimeType));
   }
   if (!mime_type_condition_values.empty()) {
-    auto mime_type_condition =
-        MakeCondition(apps::mojom::ConditionType::kMimeType,
-                      std::move(mime_type_condition_values));
-    intent_filter->conditions.push_back(std::move(mime_type_condition));
+    // For ARC view file intents, save the mime type conditions under kFile
+    // instead of kMimeType to maintain consistency with view file intents of
+    // other app types.
+    if (has_view_action) {
+      auto file_type_condition =
+          MakeCondition(apps::mojom::ConditionType::kFile,
+                        std::move(mime_type_condition_values));
+      intent_filter->conditions.push_back(std::move(file_type_condition));
+    } else {
+      auto mime_type_condition =
+          MakeCondition(apps::mojom::ConditionType::kMimeType,
+                        std::move(mime_type_condition_values));
+      intent_filter->conditions.push_back(std::move(mime_type_condition));
+    }
   }
   if (!arc_intent_filter.activity_name().empty()) {
     intent_filter->activity_name = arc_intent_filter.activity_name();
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc
index 58d8b88..07d00c1 100644
--- a/chrome/browser/apps/app_service/intent_util_unittest.cc
+++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -1197,6 +1197,56 @@
   }
 }
 
+TEST_F(IntentUtilsTest, ConvertArcIntentFilter_ReturnskFile) {
+  const char* package_name = "com.foo.bar";
+  const char* mime_type = "image/*";
+
+  arc::IntentFilter arc_filter(package_name, {arc::kIntentActionView}, {}, {},
+                               {}, {mime_type});
+
+  apps::IntentFilterPtr app_service_filter =
+      apps_util::CreateIntentFilterForArc(arc_filter);
+
+  ASSERT_EQ(app_service_filter->conditions.size(), 2U);
+  for (auto& condition : app_service_filter->conditions) {
+    // There should not be a kMimeType condition for ARC view file intent
+    // filters.
+    ASSERT_NE(condition->condition_type, apps::ConditionType::kMimeType);
+    if (condition->condition_type == apps::ConditionType::kAction) {
+      ASSERT_EQ(condition->condition_values[0]->value,
+                apps_util::kIntentActionView);
+    }
+    if (condition->condition_type == apps::ConditionType::kFile) {
+      ASSERT_EQ(condition->condition_values[0]->value, mime_type);
+    }
+  }
+}
+
+TEST_F(IntentUtilsTest, ConvertArcIntentFilter_ReturnskFile_Mojom) {
+  const char* package_name = "com.foo.bar";
+  const char* mime_type = "image/*";
+
+  arc::IntentFilter arc_filter(package_name, {arc::kIntentActionView}, {}, {},
+                               {}, {mime_type});
+
+  apps::mojom::IntentFilterPtr app_service_filter =
+      apps_util::ConvertArcToAppServiceIntentFilter(arc_filter);
+
+  ASSERT_EQ(app_service_filter->conditions.size(), 2U);
+  for (auto& condition : app_service_filter->conditions) {
+    // There should not be a kMimeType condition for ARC view file intent
+    // filters.
+    ASSERT_NE(condition->condition_type, apps::mojom::ConditionType::kMimeType);
+    if (condition->condition_type == apps::mojom::ConditionType::kAction) {
+      ASSERT_EQ(condition->condition_values[0]->value,
+                apps_util::kIntentActionView);
+    }
+    if (condition->condition_type == apps::mojom::ConditionType::kFile) {
+      ASSERT_EQ(condition->condition_values[0]->value, mime_type);
+    }
+  }
+}
+
 // TODO(crbug.com/1253250): Remove after migrating to non-mojo AppService.
 TEST_F(IntentUtilsTest,
        ConvertArcIntentFilter_WildcardHostPatternMatchTypeMojom) {
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
index 31773061..8d7acc0 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -319,7 +319,7 @@
   if (!extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile_)) {
     RunExtensionEnableFlow(
         app_id,
-        base::BindOnce(&ExtensionAppsBase::ExtensionWasEnabled,
+        base::BindOnce(&ExtensionAppsBase::LaunchAppWithIntentMojom,
                        weak_factory_.GetWeakPtr(), app_id, event_flags,
                        std::move(intent), launch_source, std::move(window_info),
                        CallbackWrapper(std::move(callback))));
@@ -481,7 +481,7 @@
 
   if (!extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile_)) {
     RunExtensionEnableFlow(
-        app_id, base::BindOnce(&ExtensionAppsBase::Launch,
+        app_id, base::BindOnce(&ExtensionAppsBase::LaunchMojom,
                                weak_factory_.GetWeakPtr(), app_id, event_flags,
                                launch_source, std::move(window_info)));
     return;
@@ -822,7 +822,14 @@
   }
 }
 
-void ExtensionAppsBase::ExtensionWasEnabled(
+void ExtensionAppsBase::LaunchMojom(const std::string& app_id,
+                                    int32_t event_flags,
+                                    apps::mojom::LaunchSource launch_source,
+                                    apps::mojom::WindowInfoPtr window_info) {
+  Launch(app_id, event_flags, std::move(launch_source), std::move(window_info));
+}
+
+void ExtensionAppsBase::LaunchAppWithIntentMojom(
     const std::string& app_id,
     int32_t event_flags,
     apps::mojom::IntentPtr intent,
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.h b/chrome/browser/apps/app_service/publishers/extension_apps_base.h
index b9e7054a..ccac0d7a 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_base.h
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.h
@@ -235,12 +235,21 @@
                      apps::mojom::Readiness readiness,
                      std::vector<apps::mojom::AppPtr>* apps_out);
 
-  void ExtensionWasEnabled(const std::string& app_id,
-                           int32_t event_flags,
-                           apps::mojom::IntentPtr intent,
-                           apps::mojom::LaunchSource launch_source,
-                           apps::mojom::WindowInfoPtr window_info,
-                           CallbackWrapper callback);
+  // TODO(crbug.com/1253250): Remove after migrating to the non mojom Launch
+  // interface.
+  void LaunchMojom(const std::string& app_id,
+                   int32_t event_flags,
+                   apps::mojom::LaunchSource launch_source,
+                   apps::mojom::WindowInfoPtr window_info);
+
+  // TODO(crbug.com/1253250): Remove after migrating to the non mojom Launch
+  // interface.
+  void LaunchAppWithIntentMojom(const std::string& app_id,
+                                int32_t event_flags,
+                                apps::mojom::IntentPtr intent,
+                                apps::mojom::LaunchSource launch_source,
+                                apps::mojom::WindowInfoPtr window_info,
+                                CallbackWrapper callback);
 
   mojo::RemoteSet<apps::mojom::Subscriber> subscribers_;
 
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
index ee35f1c..50375884 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
+++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
@@ -21,11 +21,16 @@
 #include "base/task/thread_pool.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/apps/app_service/webapk/webapk_prefs.h"
+#include "chrome/browser/apps/app_service/webapk/webapk_utils.h"
+#include "chrome/browser/ash/crosapi/crosapi_ash.h"
+#include "chrome/browser/ash/crosapi/crosapi_manager.h"
+#include "chrome/browser/ash/crosapi/web_app_service_ash.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/services/app_service/public/cpp/share_target.h"
 #include "components/version_info/version_info.h"
@@ -200,11 +205,13 @@
   DCHECK_EQ(webapk->manifest().icons_size(), 1);
 
   webapk::Image* icon = webapk->mutable_manifest()->mutable_icons(0);
-  icon->set_image_data(icon_data.data(), icon_data.size());
+  if (!icon->has_image_data()) {
+    icon->set_image_data(icon_data.data(), icon_data.size());
 
-  uint64_t icon_hash =
-      MurmurHash64A(icon_data.data(), icon_data.size(), kMurmur2HashSeed);
-  icon->set_hash(base::NumberToString(icon_hash));
+    uint64_t icon_hash =
+        MurmurHash64A(icon_data.data(), icon_data.size(), kMurmur2HashSeed);
+    icon->set_hash(base::NumberToString(icon_hash));
+  }
 
   if (web_apk_info) {
     AddUpdateParams(webapk.get(), std::move(web_apk_info));
@@ -240,12 +247,12 @@
 WebApkInstallTask::WebApkInstallTask(Profile* profile,
                                      const std::string& app_id)
     : profile_(profile),
-      web_app_provider_(web_app::WebAppProvider::GetDeprecated(profile_)),
+      web_app_provider_(web_app::WebAppProvider::GetForWebApps(profile_)),
       app_id_(app_id),
       package_name_to_update_(
           webapk_prefs::GetWebApkPackageName(profile_, app_id_)),
       minter_timeout_(kMinterResponseTimeout) {
-  DCHECK(web_app_provider_);
+  DCHECK(web_app::IsWebAppsCrosapiEnabled() || web_app_provider_);
 }
 
 WebApkInstallTask::~WebApkInstallTask() = default;
@@ -254,6 +261,11 @@
   VLOG(1) << "Generating WebAPK for app: " << app_id_;
   result_callback_ = std::move(callback);
 
+  if (web_app::IsWebAppsCrosapiEnabled()) {
+    FetchWebApkInfoFromCrosapi();
+    return;
+  }
+
   auto& registrar = web_app_provider_->registrar();
 
   // Installation & share target are already checked in WebApkManager, check
@@ -333,6 +345,12 @@
   }
   webapk->set_android_abi(GetArcAbi(arc_features.value()));
 
+  if (web_app::IsWebAppsCrosapiEnabled()) {
+    WebApkInstallTask::OnLoadedIcon(std::move(webapk), IconPurpose::ANY,
+                                    /*data=*/{});
+    return;
+  }
+
   auto& icon_manager = web_app_provider_->icon_manager();
   absl::optional<web_app::WebAppIconManager::IconSizeAndPurpose>
       icon_size_and_purpose = icon_manager.FindIconMatchBigger(
@@ -365,38 +383,7 @@
   std::string icon_url = it->url.spec();
 
   webapk::WebAppManifest* web_app_manifest = webapk->mutable_manifest();
-  web_app_manifest->set_short_name(registrar.GetAppShortName(app_id_));
-  web_app_manifest->set_start_url(registrar.GetAppStartUrl(app_id_).spec());
-  web_app_manifest->add_scopes(registrar.GetAppScope(app_id_).spec());
-
-  auto* share_target = registrar.GetAppShareTarget(app_id_);
-  webapk::ShareTarget* proto_share_target =
-      web_app_manifest->add_share_targets();
-  proto_share_target->set_action(share_target->action.spec());
-  proto_share_target->set_method(
-      apps::ShareTarget::MethodToString(share_target->method));
-  proto_share_target->set_enctype(
-      apps::ShareTarget::EnctypeToString(share_target->enctype));
-
-  webapk::ShareTargetParams* proto_params =
-      proto_share_target->mutable_params();
-  if (!share_target->params.title.empty()) {
-    proto_params->set_title(share_target->params.title);
-  }
-  if (!share_target->params.text.empty()) {
-    proto_params->set_text(share_target->params.text);
-  }
-  if (!share_target->params.url.empty()) {
-    proto_params->set_url(share_target->params.url);
-  }
-
-  for (const auto& file : share_target->params.files) {
-    webapk::ShareTargetParamsFile* proto_file = proto_params->add_files();
-    proto_file->set_name(file.name);
-    for (const auto& accept_type : file.accept) {
-      proto_file->add_accept(accept_type);
-    }
-  }
+  PopulateWebApkManifest(profile_, app_id_, web_app_manifest);
 
   webapk::Image* image = web_app_manifest->add_icons();
   image->set_src(std::move(icon_url));
@@ -414,6 +401,7 @@
 void WebApkInstallTask::OnLoadedIcon(std::unique_ptr<webapk::WebApk> webapk,
                                      IconPurpose purpose,
                                      std::vector<uint8_t> data) {
+  app_short_name_ = webapk->manifest().short_name();
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::TaskPriority::BEST_EFFORT},
       base::BindOnce(AddIconDataAndSerializeProto, std::move(webapk),
@@ -493,13 +481,11 @@
     return;
   }
 
-  auto& registrar = web_app_provider_->registrar();
-
   int webapk_version;
   base::StringToInt(response->version(), &webapk_version);
   instance->InstallWebApk(
-      response->package_name(), webapk_version,
-      registrar.GetAppShortName(app_id_), response->token(),
+      response->package_name(), webapk_version, app_short_name_,
+      response->token(),
       base::BindOnce(&WebApkInstallTask::OnInstallComplete,
                      weak_ptr_factory_.GetWeakPtr(), response->package_name()));
 }
@@ -525,6 +511,52 @@
                         : WebApkInstallStatus::kGooglePlayError);
 }
 
+void WebApkInstallTask::FetchWebApkInfoFromCrosapi() {
+  crosapi::mojom::WebAppProviderBridge* web_app_provider_bridge =
+      crosapi::CrosapiManager::Get()
+          ->crosapi_ash()
+          ->web_app_service_ash()
+          ->GetWebAppProviderBridge();
+  if (!web_app_provider_bridge) {
+    // TODO(crbug.com/1254199): Consider adding an enum entry for failures
+    // relating to Lacros.
+    DeliverResult(WebApkInstallStatus::kAppInvalid);
+    return;
+  }
+
+  web_app_provider_bridge->GetWebApkCreationParams(
+      app_id_,
+      base::BindOnce(&WebApkInstallTask::OnWebApkInfoFetchedFromCrosapi,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void WebApkInstallTask::OnWebApkInfoFetchedFromCrosapi(
+    crosapi::mojom::WebApkCreationParamsPtr webapk_creation_params) {
+  // TODO(crbug.com/1254199): Consider deserializing on another thread.
+
+  std::unique_ptr<webapk::WebApk> webapk;
+  if (webapk_creation_params &&
+      !webapk_creation_params->webapk_manifest_proto_bytes.empty()) {
+    webapk = std::make_unique<webapk::WebApk>();
+    webapk->set_manifest_url(webapk_creation_params->manifest_url);
+    if (!webapk->mutable_manifest()->ParseFromArray(
+            webapk_creation_params->webapk_manifest_proto_bytes.data(),
+            webapk_creation_params->webapk_manifest_proto_bytes.size())) {
+      webapk.reset();
+    }
+  }
+  if (!webapk) {
+    // TODO(crbug.com/1254199): Consider adding an enum entry for failures
+    // relating to Lacros.
+    DeliverResult(WebApkInstallStatus::kAppInvalid);
+    return;
+  }
+
+  webapk->set_requester_application_package(kRequesterPackageName);
+  webapk->set_requester_application_version(version_info::GetVersionNumber());
+  LoadWebApkInfo(std::move(webapk));
+}
+
 void WebApkInstallTask::DeliverResult(WebApkInstallStatus result) {
   // Invalidate weak pointers so that in-flight tasks cannot attempt to deliver
   // a second result.
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.h b/chrome/browser/apps/app_service/webapk/webapk_install_task.h
index 7d500ff..783bae8 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_install_task.h
+++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.h
@@ -17,6 +17,7 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/apps/app_service/webapk/webapk_metrics.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chromeos/crosapi/mojom/web_app_service.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
@@ -68,12 +69,16 @@
   void OnInstallComplete(const std::string& package_name,
                          arc::mojom::WebApkInstallResult result);
 
+  void FetchWebApkInfoFromCrosapi();
+  void OnWebApkInfoFetchedFromCrosapi(
+      crosapi::mojom::WebApkCreationParamsPtr webapk_creation_params);
+
   // Delivers a result to the callback. The callback can delete this task, so no
   // further work should be done after calling this method.
   void DeliverResult(WebApkInstallStatus status);
 
   Profile* const profile_;
-  web_app::WebAppProvider* web_app_provider_;
+  web_app::WebAppProvider* const web_app_provider_;
 
   arc::mojom::WebApkInfoPtr web_apk_info_;
   const std::string app_id_;
@@ -93,6 +98,10 @@
   // Fails the installation if the request to the WebAPK minter takes too long.
   base::OneShotTimer timer_;
 
+  // TODO(crbug.com/1254199): Consider passing app short name to
+  // OnProtoSerialized() and OnUrlLoaderComplete().
+  std::string app_short_name_;
+
   base::WeakPtrFactory<WebApkInstallTask> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/apps/app_service/webapk/webapk_utils.cc b/chrome/browser/apps/app_service/webapk/webapk_utils.cc
new file mode 100644
index 0000000..78c1811
--- /dev/null
+++ b/chrome/browser/apps/app_service/webapk/webapk_utils.cc
@@ -0,0 +1,202 @@
+// 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/apps/app_service/webapk/webapk_utils.h"
+
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/web_applications/web_app_icon_manager.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
+#include "components/services/app_service/public/cpp/share_target.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
+#include "third_party/smhasher/src/MurmurHash2.h"
+#include "url/gurl.h"
+
+// TODO(crbug.com/1254199): Consolidate logic with apps::WebApkInstallTask.
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+
+namespace {
+
+const SquareSizePx kMinimumIconSize = 64;
+
+// The seed to use when taking the murmur2 hash of the icon.
+const uint64_t kMurmur2HashSeed = 0;
+
+crosapi::mojom::WebApkCreationParamsPtr AddIconDataAndSerializeProto(
+    const GURL& manifest_url,
+    std::unique_ptr<webapk::WebAppManifest> webapk_manifest,
+    std::vector<uint8_t> icon_data) {
+  base::AssertLongCPUWorkAllowed();
+  DCHECK_EQ(webapk_manifest->icons_size(), 1);
+
+  webapk::Image* icon = webapk_manifest->mutable_icons(0);
+  icon->set_image_data(icon_data.data(), icon_data.size());
+
+  uint64_t icon_hash =
+      MurmurHash64A(icon_data.data(), icon_data.size(), kMurmur2HashSeed);
+  icon->set_hash(base::NumberToString(icon_hash));
+
+  std::vector<uint8_t> serialized_proto(webapk_manifest->ByteSize());
+  webapk_manifest->SerializeToArray(serialized_proto.data(),
+                                    webapk_manifest->ByteSize());
+
+  return crosapi::mojom::WebApkCreationParams::New(manifest_url.spec(),
+                                                   std::move(serialized_proto));
+}
+
+void OnLoadedIcon(apps::GetWebApkCreationParamsCallback callback,
+                  const GURL& manifest_url,
+                  std::unique_ptr<webapk::WebAppManifest> webapk_manifest,
+                  IconPurpose purpose,
+                  std::vector<uint8_t> data) {
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::TaskPriority::BEST_EFFORT},
+      base::BindOnce(AddIconDataAndSerializeProto, manifest_url,
+                     std::move(webapk_manifest), std::move(data)),
+      std::move(callback));
+}
+
+}  // namespace
+
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+namespace apps {
+
+void PopulateWebApkManifest(Profile* profile,
+                            const std::string& app_id,
+                            webapk::WebAppManifest* web_app_manifest) {
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
+  auto& registrar = provider->registrar();
+
+  // TODO(crbug.com/1254199): Call WebAppRegistrar::GetAppById(const AppId&
+  // app_id) instead of performing repeated app_id lookups.
+
+  web_app_manifest->set_short_name(registrar.GetAppShortName(app_id));
+  web_app_manifest->set_start_url(registrar.GetAppStartUrl(app_id).spec());
+  web_app_manifest->add_scopes(registrar.GetAppScope(app_id).spec());
+
+  // We currently don't set name, orientation, display_mode, theme_color,
+  // background_color, shortcuts.
+
+  auto* share_target = registrar.GetAppShareTarget(app_id);
+  webapk::ShareTarget* proto_share_target =
+      web_app_manifest->add_share_targets();
+  proto_share_target->set_action(share_target->action.spec());
+  proto_share_target->set_method(
+      apps::ShareTarget::MethodToString(share_target->method));
+  proto_share_target->set_enctype(
+      apps::ShareTarget::EnctypeToString(share_target->enctype));
+
+  webapk::ShareTargetParams* proto_params =
+      proto_share_target->mutable_params();
+  if (!share_target->params.title.empty()) {
+    proto_params->set_title(share_target->params.title);
+  }
+  if (!share_target->params.text.empty()) {
+    proto_params->set_text(share_target->params.text);
+  }
+  if (!share_target->params.url.empty()) {
+    proto_params->set_url(share_target->params.url);
+  }
+
+  for (const auto& file : share_target->params.files) {
+    webapk::ShareTargetParamsFile* proto_file = proto_params->add_files();
+    proto_file->set_name(file.name);
+    for (const auto& accept_type : file.accept) {
+      proto_file->add_accept(accept_type);
+    }
+  }
+}
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+
+void GetWebApkCreationParams(Profile* profile,
+                             const std::string& app_id,
+                             GetWebApkCreationParamsCallback callback) {
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
+  if (!provider) {
+    DVLOG(1) << "WebAppProvider is not available.";
+    std::move(callback).Run({});
+    return;
+  }
+
+  auto& registrar = provider->registrar();
+
+  // TODO(crbug.com/1254199): Call WebAppRegistrar::GetAppById(const AppId&
+  // app_id) instead of performing repeated app_id lookups.
+
+  // Installation & share target are already checked in WebApkManager, check
+  // again in case anything changed while the install request was queued.
+  // Manifest URL is always set for apps installed or updated in recent
+  // versions, but might be missing for older apps.
+  if (!registrar.IsInstalled(app_id) || !registrar.GetAppShareTarget(app_id) ||
+      registrar.GetAppManifestUrl(app_id).is_empty()) {
+    DVLOG(1) << "App is not installed, has no share target or is invalid.";
+    std::move(callback).Run({});
+    return;
+  }
+
+  auto webapk_manifest = std::make_unique<webapk::WebAppManifest>();
+
+  auto& icon_manager = provider->icon_manager();
+  absl::optional<web_app::WebAppIconManager::IconSizeAndPurpose>
+      icon_size_and_purpose = icon_manager.FindIconMatchBigger(
+          app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, kMinimumIconSize);
+
+  if (!icon_size_and_purpose) {
+    LOG(ERROR) << "Could not find suitable icon";
+    std::move(callback).Run({});
+    return;
+  }
+
+  // We need to send a URL for the icon, but it's possible the local image we're
+  // sending has been resized and so doesn't exactly match any of the images in
+  // the manifest. Since we can't be perfect, it's okay to be roughly correct
+  // and just send any URL of the correct purpose.
+  const auto& manifest_icons = registrar.GetAppIconInfos(app_id);
+  auto it = std::find_if(
+      manifest_icons.begin(), manifest_icons.end(),
+      [&icon_size_and_purpose](const apps::IconInfo& info) {
+        return info.purpose ==
+               ManifestPurposeToIconInfoPurpose(icon_size_and_purpose->purpose);
+      });
+
+  if (it == manifest_icons.end()) {
+    LOG(ERROR) << "Could not find suitable icon";
+    std::move(callback).Run({});
+    return;
+  }
+  std::string icon_url = it->url.spec();
+
+  PopulateWebApkManifest(profile, app_id, webapk_manifest.get());
+
+  webapk::Image* image = webapk_manifest->add_icons();
+  image->set_src(std::move(icon_url));
+  image->add_purposes(icon_size_and_purpose->purpose == IconPurpose::MASKABLE
+                          ? webapk::Image::MASKABLE
+                          : webapk::Image::ANY);
+  image->add_usages(webapk::Image::PRIMARY_ICON);
+
+  icon_manager.ReadSmallestCompressedIcon(
+      app_id, {icon_size_and_purpose->purpose}, icon_size_and_purpose->size_px,
+      base::BindOnce(&OnLoadedIcon, std::move(callback),
+                     registrar.GetAppManifestUrl(app_id),
+                     std::move(webapk_manifest)));
+}
+
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+}  // namespace apps
diff --git a/chrome/browser/apps/app_service/webapk/webapk_utils.h b/chrome/browser/apps/app_service/webapk/webapk_utils.h
new file mode 100644
index 0000000..a41dcc39
--- /dev/null
+++ b/chrome/browser/apps/app_service/webapk/webapk_utils.h
@@ -0,0 +1,43 @@
+// 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_APPS_APP_SERVICE_WEBAPK_WEBAPK_UTILS_H_
+#define CHROME_BROWSER_APPS_APP_SERVICE_WEBAPK_WEBAPK_UTILS_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/callback.h"
+#include "build/chromeos_buildflags.h"
+#include "chromeos/crosapi/mojom/web_app_service.mojom.h"
+#include "components/webapk/webapk.pb.h"
+
+class Profile;
+
+namespace apps {
+
+// Populates |web_app_manifest|, apart from icons, using WebAppRegistrar
+// information.
+void PopulateWebApkManifest(Profile* profile,
+                            const std::string& app_id,
+                            webapk::WebAppManifest* web_app_manifest);
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+
+using GetWebApkCreationParamsCallback = base::OnceCallback<void(
+    crosapi::mojom::WebApkCreationParamsPtr webapk_creation_params)>;
+
+// Called when a web app defining a share target has been installed in Lacros.
+// Returns the manifest URL and a serialized webapk::WebAppManifest proto
+// containing the information required for an Android WebApk to be minted.
+void GetWebApkCreationParams(Profile* profile,
+                             const std::string& app_id,
+                             GetWebApkCreationParamsCallback callback);
+
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+}  // namespace apps
+
+#endif  // CHROME_BROWSER_APPS_APP_SERVICE_WEBAPK_WEBAPK_UTILS_H_
diff --git a/chrome/browser/apps/app_service/webapk/webapk_utils_lacros_browsertest.cc b/chrome/browser/apps/app_service/webapk/webapk_utils_lacros_browsertest.cc
new file mode 100644
index 0000000..1afc1aa
--- /dev/null
+++ b/chrome/browser/apps/app_service/webapk/webapk_utils_lacros_browsertest.cc
@@ -0,0 +1,78 @@
+// 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/apps/app_service/webapk/webapk_utils.h"
+
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
+#include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
+#include "components/webapk/webapk.pb.h"
+#include "content/public/test/browser_test.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace apps {
+
+using WebApkUtilsBrowserTest = web_app::WebAppControllerBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(WebApkUtilsBrowserTest, GetWebApk) {
+  const GURL start_url =
+      https_server()->GetURL("/web_share_target/charts.html");
+  const GURL expected_manifest_url =
+      https_server()->GetURL("/web_share_target/charts.json");
+  const GURL expected_action_url =
+      https_server()->GetURL("/web_share_target/share.html");
+  const web_app::AppId app_id =
+      web_app::InstallWebAppFromManifest(browser(), start_url);
+
+  std::string manifest_url;
+  webapk::WebAppManifest manifest;
+  base::RunLoop run_loop;
+  GetWebApkCreationParams(
+      profile(), app_id,
+      base::BindLambdaForTesting(
+          [&](crosapi::mojom::WebApkCreationParamsPtr webapk_creation_params) {
+            manifest_url = webapk_creation_params->manifest_url;
+            const std::vector<uint8_t>& webapk_manifest_proto_bytes =
+                webapk_creation_params->webapk_manifest_proto_bytes;
+            ASSERT_TRUE(
+                manifest.ParseFromArray(webapk_manifest_proto_bytes.data(),
+                                        webapk_manifest_proto_bytes.size()));
+            run_loop.Quit();
+          }));
+  run_loop.Run();
+
+  EXPECT_EQ(manifest_url, expected_manifest_url.spec());
+  EXPECT_EQ(manifest.short_name(), "Charts web app");
+  EXPECT_EQ(manifest.start_url(), start_url.spec());
+  EXPECT_FALSE(manifest.has_display_mode());
+
+  ASSERT_EQ(manifest.icons_size(), 1);
+
+  ASSERT_EQ(manifest.share_targets_size(), 1);
+  const webapk::ShareTarget& share_target = manifest.share_targets(0);
+  EXPECT_EQ(share_target.action(), expected_action_url.spec());
+  EXPECT_EQ(share_target.method(), "POST");
+  EXPECT_EQ(share_target.enctype(), "multipart/form-data");
+  ASSERT_TRUE(share_target.has_params());
+  const webapk::ShareTargetParams params = share_target.params();
+  EXPECT_EQ(params.title(), "headline");
+  EXPECT_EQ(params.text(), "author");
+  EXPECT_EQ(params.url(), "link");
+  ASSERT_EQ(params.files_size(), 3);
+  {
+    const webapk::ShareTargetParamsFile& params_file = params.files(0);
+    EXPECT_EQ(params_file.name(), "records");
+  }
+  {
+    const webapk::ShareTargetParamsFile& params_file = params.files(1);
+    EXPECT_EQ(params_file.name(), "graphs");
+  }
+  {
+    const webapk::ShareTargetParamsFile& params_file = params.files(2);
+    EXPECT_EQ(params_file.name(), "notes");
+  }
+}
+
+}  // namespace apps
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index b8dab8e0..52c0563 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -664,8 +664,6 @@
     "bruschetta/bruschetta_service_factory.h",
     "bruschetta/bruschetta_util.cc",
     "bruschetta/bruschetta_util.h",
-    "bruschetta/fake_bruschetta_features.cc",
-    "bruschetta/fake_bruschetta_features.h",
     "camera_mic/vm_camera_mic_manager.cc",
     "camera_mic/vm_camera_mic_manager.h",
     "camera_presence_notifier.cc",
@@ -836,8 +834,6 @@
     "crostini/crostini_upgrader_ui_delegate.h",
     "crostini/crostini_util.cc",
     "crostini/crostini_util.h",
-    "crostini/fake_crostini_installer_ui_delegate.cc",
-    "crostini/fake_crostini_installer_ui_delegate.h",
     "crostini/termina_installer.cc",
     "crostini/termina_installer.h",
     "crostini/throttle/crostini_active_window_throttle_observer.cc",
@@ -1572,6 +1568,7 @@
     "//chromeos/ash/components/dbus/kerberos:kerberos_proto",
     "//chromeos/ash/components/dbus/os_install",
     "//chromeos/ash/components/dbus/resourced",
+    "//chromeos/ash/components/dbus/runtime_probe",
     "//chromeos/ash/components/dbus/seneschal",
     "//chromeos/ash/components/dbus/seneschal:seneschal_proto",
     "//chromeos/ash/components/dbus/services",
@@ -1605,7 +1602,6 @@
     "//chromeos/dbus/missive",
     "//chromeos/dbus/power",
     "//chromeos/dbus/power:power_manager_proto",
-    "//chromeos/dbus/runtime_probe",
     "//chromeos/dbus/tpm_manager",
     "//chromeos/dbus/tpm_manager:tpm_manager_proto",
     "//chromeos/login/login_state",
@@ -1820,6 +1816,7 @@
     "//chromeos/ash/components/dbus/federated",
     "//chromeos/ash/components/dbus/fusebox",
     "//chromeos/ash/components/dbus/human_presence",
+    "//chromeos/ash/components/dbus/image_loader",
     "//chromeos/ash/components/dbus/ip_peripheral",
     "//chromeos/ash/components/dbus/kerberos",
     "//chromeos/ash/components/dbus/lorgnette_manager",
@@ -1860,7 +1857,6 @@
     "//chromeos/dbus/dlp:dlp_proto",
     "//chromeos/dbus/easy_unlock",
     "//chromeos/dbus/hermes",
-    "//chromeos/dbus/image_loader",
     "//chromeos/dbus/init",
     "//chromeos/dbus/machine_learning",
     "//chromeos/dbus/permission_broker",
diff --git a/chrome/browser/ash/dbus/ash_dbus_helper.cc b/chrome/browser/ash/dbus/ash_dbus_helper.cc
index b9173ba5..7e8652b8 100644
--- a/chrome/browser/ash/dbus/ash_dbus_helper.cc
+++ b/chrome/browser/ash/dbus/ash_dbus_helper.cc
@@ -28,6 +28,7 @@
 #include "chromeos/ash/components/dbus/federated/federated_client.h"
 #include "chromeos/ash/components/dbus/fusebox/fusebox_reverse_client.h"
 #include "chromeos/ash/components/dbus/human_presence/human_presence_dbus_client.h"
+#include "chromeos/ash/components/dbus/image_loader/image_loader_client.h"
 #include "chromeos/ash/components/dbus/ip_peripheral/ip_peripheral_service_client.h"
 #include "chromeos/ash/components/dbus/kerberos/kerberos_client.h"
 #include "chromeos/ash/components/dbus/lorgnette_manager/lorgnette_manager_client.h"
@@ -39,6 +40,7 @@
 #include "chromeos/ash/components/dbus/resourced/resourced_client.h"
 #include "chromeos/ash/components/dbus/rgbkbd/rgbkbd_client.h"
 #include "chromeos/ash/components/dbus/rmad/rmad_client.h"
+#include "chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h"
 #include "chromeos/ash/components/dbus/seneschal/seneschal_client.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
 #include "chromeos/ash/components/dbus/smbprovider/smb_provider_client.h"
@@ -69,13 +71,11 @@
 #include "chromeos/dbus/dlp/dlp_client.h"
 #include "chromeos/dbus/hermes/hermes_clients.h"
 #include "chromeos/dbus/image_burner/image_burner_client.h"
-#include "chromeos/dbus/image_loader/image_loader_client.h"
 #include "chromeos/dbus/init/initialize_dbus_client.h"
 #include "chromeos/dbus/machine_learning/machine_learning_client.h"
 #include "chromeos/dbus/missive/missive_client.h"
 #include "chromeos/dbus/permission_broker/permission_broker_client.h"
 #include "chromeos/dbus/power/power_manager_client.h"
-#include "chromeos/dbus/runtime_probe/runtime_probe_client.h"
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "chromeos/dbus/u2f/u2f_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -152,7 +152,7 @@
   InitializeDBusClient<HibermanClient>(bus);
 #endif
   InitializeDBusClient<chromeos::ImageBurnerClient>(bus);
-  InitializeDBusClient<chromeos::ImageLoaderClient>(bus);
+  InitializeDBusClient<ImageLoaderClient>(bus);
   InitializeDBusClient<InstallAttributesClient>(bus);
   InitializeDBusClient<IpPeripheralServiceClient>(bus);
   InitializeDBusClient<KerberosClient>(bus);
@@ -167,7 +167,7 @@
   InitializeDBusClient<chromeos::PermissionBrokerClient>(bus);
   InitializeDBusClient<chromeos::PowerManagerClient>(bus);
   InitializeDBusClient<ResourcedClient>(bus);
-  InitializeDBusClient<chromeos::RuntimeProbeClient>(bus);
+  InitializeDBusClient<RuntimeProbeClient>(bus);
   InitializeDBusClient<SeneschalClient>(bus);
   InitializeDBusClient<SessionManagerClient>(bus);
   InitializeDBusClient<SmbProviderClient>(bus);
@@ -251,7 +251,7 @@
   SmbProviderClient::Shutdown();
   SessionManagerClient::Shutdown();
   SeneschalClient::Shutdown();
-  chromeos::RuntimeProbeClient::Shutdown();
+  RuntimeProbeClient::Shutdown();
   ResourcedClient::Shutdown();
   if (ash::features::IsRgbKeyboardEnabled()) {
     RgbkbdClient::Shutdown();
@@ -272,7 +272,7 @@
   KerberosClient::Shutdown();
   IpPeripheralServiceClient::Shutdown();
   InstallAttributesClient::Shutdown();
-  chromeos::ImageLoaderClient::Shutdown();
+  ImageLoaderClient::Shutdown();
   chromeos::ImageBurnerClient::Shutdown();
 #if BUILDFLAG(ENABLE_HIBERNATE)
   HibermanClient::Shutdown();
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks.cc b/chrome/browser/ash/file_manager/app_service_file_tasks.cc
index 88b70eb..d20dd29 100644
--- a/chrome/browser/ash/file_manager/app_service_file_tasks.cc
+++ b/chrome/browser/ash/file_manager/app_service_file_tasks.cc
@@ -9,8 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/components/arc/mojom/file_system.mojom.h"
-#include "ash/components/arc/mojom/intent_helper.mojom.h"
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
@@ -34,7 +32,6 @@
 #include "chrome/browser/web_applications/web_app_id_constants.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/extensions/api/file_manager_private.h"
-#include "components/arc/intent_helper/intent_constants.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/services/app_service/public/mojom/types.mojom-shared.h"
@@ -53,12 +50,8 @@
 using extensions::api::file_manager_private::Verb;
 
 namespace {
-// TODO(crbug/1092784): Only going to support ARC app and web app
-// for now.
 TaskType GetTaskType(apps::AppType app_type) {
   switch (app_type) {
-    case apps::AppType::kArc:
-      return TASK_TYPE_ARC_APP;
     case apps::AppType::kWeb:
     case apps::AppType::kSystemWeb:
       return TASK_TYPE_WEB_APP;
@@ -71,6 +64,7 @@
       // because both are executed through App Service, which can tell the
       // difference itself.
       return TASK_TYPE_FILE_HANDLER;
+    case apps::AppType::kArc:
     case apps::AppType::kUnknown:
     case apps::AppType::kCrostini:
     case apps::AppType::kBuiltIn:
@@ -160,7 +154,7 @@
 
   for (auto& launch_entry : intent_launch_info) {
     auto app_type = proxy->AppRegistryCache().GetAppType(launch_entry.app_id);
-    if (!(app_type == apps::AppType::kArc || app_type == apps::AppType::kWeb ||
+    if (!(app_type == apps::AppType::kWeb ||
           app_type == apps::AppType::kSystemWeb ||
           app_type == apps::AppType::kChromeApp ||
           app_type == apps::AppType::kExtension ||
@@ -261,13 +255,10 @@
     intent_files.push_back(std::move(file));
   }
 
-  DCHECK(task.task_type == TASK_TYPE_ARC_APP ||
-         task.task_type == TASK_TYPE_WEB_APP ||
+  DCHECK(task.task_type == TASK_TYPE_WEB_APP ||
          task.task_type == TASK_TYPE_FILE_HANDLER);
   apps::mojom::IntentPtr intent =
-      task.task_type == TASK_TYPE_ARC_APP
-          ? apps_util::CreateShareIntentFromFiles(file_urls, mime_types)
-          : apps_util::CreateViewIntentFromFiles(std::move(intent_files));
+      apps_util::CreateViewIntentFromFiles(std::move(intent_files));
   intent->activity_name = task.action_id;
 
   apps::AppServiceProxyFactory::GetForProfile(profile)->LaunchAppWithIntent(
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc
index fdfbafb1..638540b1 100644
--- a/chrome/browser/ash/file_manager/file_tasks.cc
+++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -359,7 +359,7 @@
 
     // Remove Web Drive Office action if Web Drive Office is disabled.
     if (IsCandidateWebDriveOffice() &&
-        !base::FeatureList::IsEnabled(ash::features::kFilesWebDriveOffice)) {
+        !ash::features::IsFilesWebDriveOfficeEnabled()) {
       UMA_HISTOGRAM_ENUMERATION(kWebDriveOfficeMetricName,
                                 WebDriveOfficeTaskResult::FLAG_DISABLED);
       InvalidateCandidate();
@@ -369,7 +369,7 @@
 
     // Remove Upload to Drive action if its flag is disabled.
     if (IsCandidateUploadOfficeToDrive() &&
-        !base::FeatureList::IsEnabled(ash::features::kUploadOfficeToCloud)) {
+        !ash::features::IsUploadOfficeToCloudEnabled()) {
       InvalidateCandidate();
       EndAdjustTasks();
       return;
@@ -580,12 +580,8 @@
     FileTaskFinishedCallback done,
     extensions::app_file_handler_util::MimeTypeCollector* mime_collector,
     std::unique_ptr<std::vector<std::string>> mime_types) {
-  bool is_arc_share = task.task_type == TASK_TYPE_ARC_APP &&
-                      (task.action_id == kActionIdSend ||
-                       task.action_id == kActionIdSendMultiple);
-  bool is_web_app = task.task_type == TASK_TYPE_WEB_APP;
-  bool is_chrome_app = task.task_type == TASK_TYPE_FILE_HANDLER;
-  if (is_arc_share || is_web_app || is_chrome_app) {
+  if (task.task_type == TASK_TYPE_WEB_APP ||
+      task.task_type == TASK_TYPE_FILE_HANDLER) {
     ExecuteAppServiceTask(profile, task, file_urls, *mime_types,
                           std::move(done));
     return;
diff --git a/chrome/browser/ash/login/demo_mode/demo_resources.cc b/chrome/browser/ash/login/demo_mode/demo_resources.cc
index 1d4c047..0c3abd9 100644
--- a/chrome/browser/ash/login/demo_mode/demo_resources.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_resources.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/image_loader/image_loader_client.h"
 
 namespace ash {
 namespace {
diff --git a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
index 6a35a5d9..3323a4b 100644
--- a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
@@ -31,10 +31,10 @@
 #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_settings.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
+#include "chromeos/ash/services/assistant/public/proto/activity_control_settings_common.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/get_settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/ash/services/assistant/service.h"
-#include "chromeos/services/assistant/public/proto/activity_control_settings_common.pb.h"
-#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_test.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.cc
new file mode 100644
index 0000000..798ab24
--- /dev/null
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.cc
@@ -0,0 +1,50 @@
+// 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/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h"
+
+#include <limits>
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "components/reporting/metrics/sampler.h"
+#include "components/reporting/proto/synced/metric_data.pb.h"
+#include "services/network/public/cpp/network_quality_tracker.h"
+
+namespace reporting {
+
+NetworkBandwidthSampler::NetworkBandwidthSampler(
+    ::network::NetworkQualityTracker* network_quality_tracker,
+    Profile* profile)
+    : network_quality_tracker_(network_quality_tracker), profile_(profile) {
+  DCHECK(network_quality_tracker_);
+}
+
+void NetworkBandwidthSampler::MaybeCollect(OptionalMetricCallback callback) {
+  DCHECK(profile_);
+  if (!profile_->GetPrefs()->GetBoolean(::prefs::kInsightsExtensionEnabled)) {
+    // Policy not set, so we return.
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+
+  const auto downlink_speed_kbps =
+      network_quality_tracker_->GetDownstreamThroughputKbps();
+  if (downlink_speed_kbps == std::numeric_limits<int32_t>::max()) {
+    // Network quality tracker returns std::numeric_limits<int32_t>::max() if
+    // downstream throughput is unavailable, so we return no data.
+    std::move(callback).Run(absl::nullopt);
+    return;
+  }
+
+  MetricData metric_data;
+  metric_data.mutable_telemetry_data()
+      ->mutable_networks_telemetry()
+      ->mutable_bandwidth_data()
+      ->set_download_speed_kbps(downlink_speed_kbps);
+  std::move(callback).Run(metric_data);
+}
+
+}  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h
new file mode 100644
index 0000000..f6fd307a
--- /dev/null
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h
@@ -0,0 +1,40 @@
+// 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_POLICY_REPORTING_METRICS_REPORTING_NETWORK_NETWORK_BANDWIDTH_SAMPLER_H_
+#define CHROME_BROWSER_ASH_POLICY_REPORTING_METRICS_REPORTING_NETWORK_NETWORK_BANDWIDTH_SAMPLER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/reporting/metrics/sampler.h"
+#include "services/network/public/cpp/network_quality_tracker.h"
+
+namespace reporting {
+
+// Sampler used to collect network bandwidth information like download speed
+// (in kbps). This sampler relies on the `NetworkQualityTracker` defined in
+// the `NetworkService` to collect said metrics.
+class NetworkBandwidthSampler : public Sampler {
+ public:
+  NetworkBandwidthSampler(
+      ::network::NetworkQualityTracker* network_quality_tracker,
+      Profile* profile);
+  NetworkBandwidthSampler(const NetworkBandwidthSampler& other) = delete;
+  NetworkBandwidthSampler& operator=(const NetworkBandwidthSampler& other) =
+      delete;
+  ~NetworkBandwidthSampler() override = default;
+
+  // Collects network bandwidth info if the corresponding user policy is set
+  // and reports collected metrics using the specified callback. Reports
+  // `absl::nullopt` otherwise.
+  void MaybeCollect(OptionalMetricCallback callback) override;
+
+ private:
+  const raw_ptr<::network::NetworkQualityTracker> network_quality_tracker_;
+  const raw_ptr<Profile> profile_;
+};
+
+}  // namespace reporting
+
+#endif  // CHROME_BROWSER_ASH_POLICY_REPORTING_METRICS_REPORTING_NETWORK_NETWORK_BANDWIDTH_SAMPLER_H_
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler_unittest.cc
new file mode 100644
index 0000000..072b2f2
--- /dev/null
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler_unittest.cc
@@ -0,0 +1,122 @@
+// 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/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h"
+
+#include "base/test/task_environment.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/reporting/proto/synced/metric_data.pb.h"
+#include "components/reporting/util/test_support_callbacks.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace reporting {
+namespace {
+
+constexpr int64_t kInitDownloadSpeedKbps = 100;
+
+class NetworkBandwidthSamplerTest : public ::testing::Test {
+ protected:
+  NetworkBandwidthSamplerTest() { EXPECT_TRUE(profile_manager_.SetUp()); }
+
+  void SetUp() override {
+    profile_ = profile_manager_.CreateTestingProfile("test-user");
+  }
+
+  void UpdateDownloadSpeedKbps(int64_t download_speed_kbps) {
+    g_browser_process->network_quality_tracker()
+        ->ReportRTTsAndThroughputForTesting(base::Milliseconds(100),
+                                            download_speed_kbps);
+    task_environment_.RunUntilIdle();
+  }
+
+  void SetPrefValue(bool value) {
+    profile_->GetPrefs()->SetBoolean(::prefs::kInsightsExtensionEnabled, value);
+    task_environment_.RunUntilIdle();
+  }
+
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
+  raw_ptr<Profile> profile_;
+};
+
+TEST_F(NetworkBandwidthSamplerTest, DoesNotReportDownloadSpeedByDefault) {
+  UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps);
+  NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
+                                  profile_);
+
+  ::reporting::test::TestEvent<absl::optional<MetricData>> test_event;
+  sampler.MaybeCollect(test_event.cb());
+  auto result = test_event.result();
+  ASSERT_FALSE(result.has_value());
+}
+
+TEST_F(NetworkBandwidthSamplerTest, ReportsDownloadSpeedWhenPrefSet) {
+  SetPrefValue(true);
+  UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps);
+  NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
+                                  profile_);
+
+  ::reporting::test::TestEvent<absl::optional<MetricData>> test_event;
+  sampler.MaybeCollect(test_event.cb());
+  auto result = test_event.result();
+  ASSERT_TRUE(result.has_value());
+  EXPECT_EQ(result->mutable_telemetry_data()
+                ->mutable_networks_telemetry()
+                ->mutable_bandwidth_data()
+                ->download_speed_kbps(),
+            kInitDownloadSpeedKbps);
+}
+
+TEST_F(NetworkBandwidthSamplerTest, DoesNotReportDownloadSpeedWhenPrefUnset) {
+  SetPrefValue(false);
+  UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps);
+  NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
+                                  profile_);
+
+  ::reporting::test::TestEvent<absl::optional<MetricData>> test_event;
+  sampler.MaybeCollect(test_event.cb());
+  auto result = test_event.result();
+  ASSERT_FALSE(result.has_value());
+}
+
+TEST_F(NetworkBandwidthSamplerTest, DoesNotReportDownloadSpeedIfUnavailable) {
+  SetPrefValue(true);
+  NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
+                                  profile_);
+
+  ::reporting::test::TestEvent<absl::optional<MetricData>> test_event;
+  sampler.MaybeCollect(test_event.cb());
+  auto result = test_event.result();
+  ASSERT_FALSE(result.has_value());
+}
+
+TEST_F(NetworkBandwidthSamplerTest, ReportsUpdatedDownloadSpeed) {
+  SetPrefValue(true);
+  UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps);
+  NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
+                                  profile_);
+
+  // Update download speed so we can verify that the sampler reports the new
+  // value.
+  const int64_t download_speed_kbps = 100000;
+  UpdateDownloadSpeedKbps(download_speed_kbps);
+
+  ::reporting::test::TestEvent<absl::optional<MetricData>> test_event;
+  sampler.MaybeCollect(test_event.cb());
+  auto result = test_event.result();
+  ASSERT_TRUE(result.has_value());
+  EXPECT_EQ(result->mutable_telemetry_data()
+                ->mutable_networks_telemetry()
+                ->mutable_bandwidth_data()
+                ->download_speed_kbps(),
+            download_speed_kbps);
+}
+
+}  // namespace
+}  // namespace reporting
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index 1686f43a7..e2036ab 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -1235,71 +1235,6 @@
       }
     }
 
-    // Process SystemResult.
-    const auto& system_result = probe_result->system_result;
-    if (!system_result.is_null()) {
-      switch (system_result->which()) {
-        case cros_healthd::SystemResult::Tag::kError: {
-          LOG(ERROR) << "cros_healthd: Error getting system info: "
-                     << system_result->get_error()->msg;
-          break;
-        }
-
-        case cros_healthd::SystemResult::Tag::kSystemInfo: {
-          const auto& system_info = system_result->get_system_info();
-          em::SystemStatus* const system_status_out =
-              response_params_.device_status->mutable_system_status();
-          if (report_vpd_info) {
-            if (system_info->first_power_date.has_value()) {
-              system_status_out->set_first_power_date(
-                  system_info->first_power_date.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->manufacture_date.has_value()) {
-              system_status_out->set_manufacture_date(
-                  system_info->manufacture_date.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->product_sku_number.has_value()) {
-              system_status_out->set_vpd_sku_number(
-                  system_info->product_sku_number.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->product_serial_number.has_value()) {
-              system_status_out->set_vpd_serial_number(
-                  system_info->product_serial_number.value());
-              SetDeviceStatusReported();
-            }
-          }
-          if (report_system_info) {
-            system_status_out->set_marketing_name(system_info->marketing_name);
-            if (system_info->bios_version.has_value()) {
-              system_status_out->set_bios_version(
-                  system_info->bios_version.value());
-            }
-            if (system_info->board_name.has_value()) {
-              system_status_out->set_board_name(
-                  system_info->board_name.value());
-            }
-            if (system_info->board_version.has_value()) {
-              system_status_out->set_board_version(
-                  system_info->board_version.value());
-            }
-            if (system_info->chassis_type) {
-              system_status_out->set_chassis_type(
-                  system_info->chassis_type->value);
-            }
-            if (system_info->product_name.has_value()) {
-              system_status_out->set_product_name(
-                  system_info->product_name.value());
-            }
-            SetDeviceStatusReported();
-          }
-          break;
-        }
-      }
-    }
-
     // Process SystemResultV2.
     const auto& system_result_v2 = probe_result->system_result_v2;
     if (!system_result_v2.is_null()) {
@@ -1316,6 +1251,59 @@
         // info below.
         case cros_healthd::SystemResultV2::Tag::kSystemInfoV2: {
           const auto& system_info_v2 = system_result_v2->get_system_info_v2();
+
+          if (report_vpd_info || report_system_info) {
+            em::SystemStatus* const system_status_out =
+                response_params_.device_status->mutable_system_status();
+            if (report_vpd_info) {
+              if (system_info_v2->vpd_info->activate_date.has_value()) {
+                system_status_out->set_first_power_date(
+                    system_info_v2->vpd_info->activate_date.value());
+                SetDeviceStatusReported();
+              }
+              if (system_info_v2->vpd_info->mfg_date.has_value()) {
+                system_status_out->set_manufacture_date(
+                    system_info_v2->vpd_info->mfg_date.value());
+                SetDeviceStatusReported();
+              }
+              if (system_info_v2->vpd_info->sku_number.has_value()) {
+                system_status_out->set_vpd_sku_number(
+                    system_info_v2->vpd_info->sku_number.value());
+                SetDeviceStatusReported();
+              }
+              if (system_info_v2->vpd_info->serial_number.has_value()) {
+                system_status_out->set_vpd_serial_number(
+                    system_info_v2->vpd_info->serial_number.value());
+                SetDeviceStatusReported();
+              }
+            }
+            if (report_system_info) {
+              if (system_info_v2->os_info->marketing_name.has_value()) {
+                system_status_out->set_marketing_name(
+                    system_info_v2->os_info->marketing_name.value());
+              }
+              if (system_info_v2->dmi_info->bios_version.has_value()) {
+                system_status_out->set_bios_version(
+                    system_info_v2->dmi_info->bios_version.value());
+              }
+              if (system_info_v2->dmi_info->board_name.has_value()) {
+                system_status_out->set_board_name(
+                    system_info_v2->dmi_info->board_name.value());
+              }
+              if (system_info_v2->dmi_info->board_version.has_value()) {
+                system_status_out->set_board_version(
+                    system_info_v2->dmi_info->board_version.value());
+              }
+              if (system_info_v2->dmi_info->chassis_type) {
+                system_status_out->set_chassis_type(
+                    system_info_v2->dmi_info->chassis_type->value);
+              }
+              system_status_out->set_product_name(
+                  system_info_v2->os_info->code_name);
+              SetDeviceStatusReported();
+            }
+          }
+
           em::SmbiosInfo* const smbios_info_out =
               response_params_.device_status->mutable_smbios_info();
           if (!system_info_v2->dmi_info.is_null()) {
@@ -2684,12 +2672,9 @@
 
   std::vector<ProbeCategoryEnum> probe_categories;
 
-  // Always probe System2 to get device vendor, product name, and product
+  // Always probe System to get device vendor, product name, and product
   // version
-  probe_categories.push_back(ProbeCategoryEnum::kSystem2);
-
-  if (report_vpd_info_ || report_system_info_)
-    probe_categories.push_back(ProbeCategoryEnum::kSystem);
+  probe_categories.push_back(ProbeCategoryEnum::kSystem);
 
   if (report_timezone_info_)
     probe_categories.push_back(ProbeCategoryEnum::kTimezone);
@@ -2953,8 +2938,8 @@
   return report_power_status_ || report_storage_status_ ||
          report_audio_status_ || report_board_status_ || report_memory_info_ ||
          report_cpu_info_ || report_backlight_info_ || report_bluetooth_info_ ||
-         report_fan_info_ || report_vpd_info_ || report_system_info_ || report_boot_mode_ ||
-         report_version_info_;
+         report_fan_info_ || report_vpd_info_ || report_system_info_ ||
+         report_boot_mode_ || report_version_info_;
 }
 bool DeviceStatusCollector::IsReportingUsers() const {
   // For more details, see comment in
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
index ca61a2f..70857d3 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -160,41 +160,35 @@
 constexpr char kFakeBatteryTechnology[] = "fake_battery_technology";
 constexpr char kFakeBatteryStatus[] = "fake_battery_status";
 // System test values:
-const char kFakeFirstPowerDate[] = "2020-40";
-const char kFakeManufactureDate[] = "2019-01-01";
-const char kFakeSkuNumber[] = "ABCD&^A";
-const char kFakeSerialNumber[] = "8607G03EDF";
-constexpr char kFakeSystemModelName[] = "XX ModelName 007 XY";
-constexpr char kFakeMarketingName[] = "Latitude 1234 Chromebook Enterprise";
-constexpr char kFakeBiosVersion[] = "Google_BoardName.12200.68.0";
-constexpr char kFakeBoardName[] = "BoardName";
-constexpr char kFakeBoardVersion[] = "rev1234";
-constexpr uint64_t kFakeChassisType = 9;
-constexpr char kFakeProductName[] = "ProductName";
-constexpr char kFakeVersionMilestone[] = "87";
-constexpr char kFakeVersionBuildNumber[] = "13544";
-constexpr char kFakeVersionPatchNumber[] = "59.0";
-constexpr char kFakeVersionReleaseChannel[] = "stable-channel";
-// System V2 test values:
-constexpr char kFakeOsInfoCodeName[] = "OsInfo Code Name";
-constexpr char kFakeOSInfoMarketingName[] = "OsInfo Marketing Name";
-constexpr char kFakeOSInfoOemName[] = "OsInfo OEM Name";
-constexpr cros_healthd::BootMode kFakeOsInfoBootMode =
-    cros_healthd::BootMode::kCrosSecure;
-constexpr em::BootInfo::BootMethod kFakeOsInfoBootMethod =
-    em::BootInfo::CROS_SECURE;
-constexpr char kFakeVpdInfoRegion[] = "VpdInfo Region";
 constexpr char kFakeDmiInfoBiosVendor[] = "DMI Bios Vendor";
-constexpr char kFakeDmiInfoBiosVersion[] = "DMI Bios Version";
+constexpr char kFakeDmiInfoBiosVersion[] = "Google_BoardName.12200.68.0";
 constexpr char kFakeDmiInfoBoardName[] = "DMI Board Name";
 constexpr char kFakeDmiInfoBoardVendor[] = "DMI Board Vendor";
-constexpr char kFakeDmiInfoBoardVersion[] = "DMI Board Version";
-constexpr char kFakeDmiInfoChassisVendor[] = "DMI Chassis Vendor";
+constexpr char kFakeDmiInfoBoardVersion[] = "rev1234";
 constexpr uint64_t kFakeDmiInfoChassisType = 9;
+constexpr char kFakeDmiInfoChassisVendor[] = "DMI Chassis Vendor";
 constexpr char kFakeDmiInfoProductFamily[] = "DMI Product Family";
-constexpr char kFakeDmiInfoSysVendor[] = "DMI System Vendor";
 constexpr char kFakeDmiInfoProductName[] = "DMI Product Name";
 constexpr char kFakeDmiInfoProductVersion[] = "DMI Product Version";
+constexpr char kFakeDmiInfoSysVendor[] = "DMI System Vendor";
+constexpr em::BootInfo::BootMethod kFakeOsInfoBootMethod =
+    em::BootInfo::CROS_SECURE;
+constexpr cros_healthd::BootMode kFakeOsInfoBootMode =
+    cros_healthd::BootMode::kCrosSecure;
+constexpr char kFakeOsInfoMarketingName[] =
+    "Latitude 1234 Chromebook Enterprise";
+constexpr char kFakeOsInfoOemName[] = "OsInfo OEM Name";
+constexpr char kFakeOsInfoProductName[] = "OsInfo Code Name";
+constexpr char kFakeOsVersionBuildNumber[] = "13544";
+constexpr char kFakeOsVersionMilestone[] = "87";
+constexpr char kFakeOsVersionPatchNumber[] = "59.0";
+constexpr char kFakeOsVersionReleaseChannel[] = "stable-channel";
+constexpr char kFakeVpdInfoFirstPowerDate[] = "2020-40";
+constexpr char kFakeVpdInfoManufactureDate[] = "2019-01-01";
+constexpr char kFakeVpdInfoRegion[] = "VpdInfo Region";
+constexpr char kFakeVpdInfoSerialNumber[] = "8607G03EDF";
+constexpr char kFakeVpdInfoSkuNumber[] = "ABCD&^A";
+constexpr char kFakeVpdInfoSystemModelName[] = "XX ModelName 007 XY";
 // CPU test values:
 constexpr uint32_t kFakeNumTotalThreads = 8;
 constexpr char kFakeModelName[] = "fake_cpu_model_name";
@@ -570,30 +564,19 @@
       std::move(storage_vector));
 }
 
-cros_healthd::SystemResultPtr CreateSystemResult() {
-  return cros_healthd::SystemResult::NewSystemInfo(
-      cros_healthd::SystemInfo::New(
-          kFakeFirstPowerDate, kFakeManufactureDate, kFakeSkuNumber,
-          kFakeSerialNumber, kFakeSystemModelName, kFakeMarketingName,
-          kFakeBiosVersion, kFakeBoardName, kFakeBoardVersion,
-          cros_healthd::NullableUint64::New(kFakeChassisType), kFakeProductName,
-          cros_healthd::OsVersion::New(
-              kFakeVersionMilestone, kFakeVersionBuildNumber,
-              kFakeVersionPatchNumber, kFakeVersionReleaseChannel)));
-}
-
 cros_healthd::SystemResultV2Ptr CreateSystemResultV2() {
   return cros_healthd::SystemResultV2::NewSystemInfoV2(
       cros_healthd::SystemInfoV2::New(
           cros_healthd::OsInfo::New(
-              kFakeOsInfoCodeName, kFakeOSInfoMarketingName,
+              kFakeOsInfoProductName, kFakeOsInfoMarketingName,
               cros_healthd::OsVersion::New(
-                  kFakeVersionMilestone, kFakeVersionBuildNumber,
-                  kFakeVersionPatchNumber, kFakeVersionReleaseChannel),
-              kFakeOsInfoBootMode, kFakeOSInfoOemName),
-          cros_healthd::VpdInfo::New(kFakeSerialNumber, kFakeVpdInfoRegion,
-                                     kFakeManufactureDate, kFakeFirstPowerDate,
-                                     kFakeSkuNumber, kFakeModelName),
+                  kFakeOsVersionMilestone, kFakeOsVersionBuildNumber,
+                  kFakeOsVersionPatchNumber, kFakeOsVersionReleaseChannel),
+              kFakeOsInfoBootMode, kFakeOsInfoOemName),
+          cros_healthd::VpdInfo::New(
+              kFakeVpdInfoSerialNumber, kFakeVpdInfoRegion,
+              kFakeVpdInfoManufactureDate, kFakeVpdInfoFirstPowerDate,
+              kFakeVpdInfoSkuNumber, kFakeVpdInfoSystemModelName),
           cros_healthd::DmiInfo::New(
               kFakeDmiInfoBiosVendor, kFakeDmiInfoBiosVersion,
               kFakeDmiInfoBoardName, kFakeDmiInfoBoardVendor,
@@ -769,9 +752,6 @@
     telemetry_info->battery_result = CreateBatteryResult();
   if (SettingEnabled(ash::kReportDeviceStorageStatus))
     telemetry_info->block_device_result = CreateBlockDeviceResult();
-  if (SettingEnabled(ash::kReportDeviceSystemInfo) ||
-      SettingEnabled(ash::kReportDeviceVpdInfo))
-    telemetry_info->system_result = CreateSystemResult();
   if (SettingEnabled(ash::kReportDeviceCpuInfo))
     telemetry_info->cpu_result = CreateCpuResult();
   if (SettingEnabled(ash::kReportDeviceTimezoneInfo))
@@ -3651,12 +3631,13 @@
   // Verify the only vpd info is populated.
   ASSERT_TRUE(device_status_.has_system_status());
   EXPECT_EQ(device_status_.system_status().first_power_date(),
-            kFakeFirstPowerDate);
+            kFakeVpdInfoFirstPowerDate);
   EXPECT_EQ(device_status_.system_status().manufacture_date(),
-            kFakeManufactureDate);
-  EXPECT_EQ(device_status_.system_status().vpd_sku_number(), kFakeSkuNumber);
+            kFakeVpdInfoManufactureDate);
+  EXPECT_EQ(device_status_.system_status().vpd_sku_number(),
+            kFakeVpdInfoSkuNumber);
   EXPECT_EQ(device_status_.system_status().vpd_serial_number(),
-            kFakeSerialNumber);
+            kFakeVpdInfoSerialNumber);
   ASSERT_FALSE(device_status_.system_status().has_marketing_name());
   ASSERT_FALSE(device_status_.system_status().has_bios_version());
   ASSERT_FALSE(device_status_.system_status().has_board_name());
@@ -3689,12 +3670,16 @@
   ASSERT_FALSE(device_status_.system_status().has_manufacture_date());
   ASSERT_FALSE(device_status_.system_status().has_vpd_sku_number());
   EXPECT_EQ(device_status_.system_status().marketing_name(),
-            kFakeMarketingName);
-  EXPECT_EQ(device_status_.system_status().bios_version(), kFakeBiosVersion);
-  EXPECT_EQ(device_status_.system_status().board_name(), kFakeBoardName);
-  EXPECT_EQ(device_status_.system_status().board_version(), kFakeBoardVersion);
-  EXPECT_EQ(device_status_.system_status().chassis_type(), kFakeChassisType);
-  EXPECT_EQ(device_status_.system_status().product_name(), kFakeProductName);
+            kFakeOsInfoMarketingName);
+  EXPECT_EQ(device_status_.system_status().bios_version(),
+            kFakeDmiInfoBiosVersion);
+  EXPECT_EQ(device_status_.system_status().board_name(), kFakeDmiInfoBoardName);
+  EXPECT_EQ(device_status_.system_status().board_version(),
+            kFakeDmiInfoBoardVersion);
+  EXPECT_EQ(device_status_.system_status().chassis_type(),
+            kFakeDmiInfoChassisType);
+  EXPECT_EQ(device_status_.system_status().product_name(),
+            kFakeOsInfoProductName);
 
   // Verify system info V2 exists too.
   ASSERT_TRUE(device_status_.has_smbios_info());
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
index 7209484..54fc7e1 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
@@ -1232,71 +1232,6 @@
       }
     }
 
-    // Process SystemResult.
-    const auto& system_result = probe_result->system_result;
-    if (!system_result.is_null()) {
-      switch (system_result->which()) {
-        case cros_healthd::SystemResult::Tag::kError: {
-          LOG(ERROR) << "cros_healthd: Error getting system info: "
-                     << system_result->get_error()->msg;
-          break;
-        }
-
-        case cros_healthd::SystemResult::Tag::kSystemInfo: {
-          const auto& system_info = system_result->get_system_info();
-          em::SystemStatus* const system_status_out =
-              response_params_.device_status->mutable_system_status();
-          if (report_vpd_info) {
-            if (system_info->first_power_date.has_value()) {
-              system_status_out->set_first_power_date(
-                  system_info->first_power_date.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->manufacture_date.has_value()) {
-              system_status_out->set_manufacture_date(
-                  system_info->manufacture_date.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->product_sku_number.has_value()) {
-              system_status_out->set_vpd_sku_number(
-                  system_info->product_sku_number.value());
-              SetDeviceStatusReported();
-            }
-            if (system_info->product_serial_number.has_value()) {
-              system_status_out->set_vpd_serial_number(
-                  system_info->product_serial_number.value());
-              SetDeviceStatusReported();
-            }
-          }
-          if (report_system_info) {
-            system_status_out->set_marketing_name(system_info->marketing_name);
-            if (system_info->bios_version.has_value()) {
-              system_status_out->set_bios_version(
-                  system_info->bios_version.value());
-            }
-            if (system_info->board_name.has_value()) {
-              system_status_out->set_board_name(
-                  system_info->board_name.value());
-            }
-            if (system_info->board_version.has_value()) {
-              system_status_out->set_board_version(
-                  system_info->board_version.value());
-            }
-            if (system_info->chassis_type) {
-              system_status_out->set_chassis_type(
-                  system_info->chassis_type->value);
-            }
-            if (system_info->product_name.has_value()) {
-              system_status_out->set_product_name(
-                  system_info->product_name.value());
-            }
-            SetDeviceStatusReported();
-          }
-          break;
-        }
-      }
-    }
-
     // Process SystemResultV2.
     const auto& system_result_v2 = probe_result->system_result_v2;
     if (!system_result_v2.is_null()) {
@@ -1309,6 +1244,57 @@
 
         case cros_healthd::SystemResultV2::Tag::kSystemInfoV2: {
           const auto& system_info_v2 = system_result_v2->get_system_info_v2();
+
+          em::SystemStatus* const system_status_out =
+              response_params_.device_status->mutable_system_status();
+          if (report_vpd_info) {
+            if (system_info_v2->vpd_info->activate_date.has_value()) {
+              system_status_out->set_first_power_date(
+                  system_info_v2->vpd_info->activate_date.value());
+              SetDeviceStatusReported();
+            }
+            if (system_info_v2->vpd_info->mfg_date.has_value()) {
+              system_status_out->set_manufacture_date(
+                  system_info_v2->vpd_info->mfg_date.value());
+              SetDeviceStatusReported();
+            }
+            if (system_info_v2->vpd_info->sku_number.has_value()) {
+              system_status_out->set_vpd_sku_number(
+                  system_info_v2->vpd_info->sku_number.value());
+              SetDeviceStatusReported();
+            }
+            if (system_info_v2->vpd_info->serial_number.has_value()) {
+              system_status_out->set_vpd_serial_number(
+                  system_info_v2->vpd_info->serial_number.value());
+              SetDeviceStatusReported();
+            }
+          }
+          if (report_system_info) {
+            if (system_info_v2->os_info->marketing_name.has_value()) {
+              system_status_out->set_marketing_name(
+                  system_info_v2->os_info->marketing_name.value());
+            }
+            if (system_info_v2->dmi_info->bios_version.has_value()) {
+              system_status_out->set_bios_version(
+                  system_info_v2->dmi_info->bios_version.value());
+            }
+            if (system_info_v2->dmi_info->board_name.has_value()) {
+              system_status_out->set_board_name(
+                  system_info_v2->dmi_info->board_name.value());
+            }
+            if (system_info_v2->dmi_info->board_version.has_value()) {
+              system_status_out->set_board_version(
+                  system_info_v2->dmi_info->board_version.value());
+            }
+            if (system_info_v2->dmi_info->chassis_type) {
+              system_status_out->set_chassis_type(
+                  system_info_v2->dmi_info->chassis_type->value);
+            }
+            system_status_out->set_product_name(
+                system_info_v2->os_info->code_name);
+            SetDeviceStatusReported();
+          }
+
           em::SmbiosInfo* const smbios_info_out =
               response_params_.device_status->mutable_smbios_info();
           em::BootInfo* const boot_info_out =
@@ -2005,7 +1991,6 @@
     case CrosHealthdCollectionMode::kFull: {
       if (report_vpd_info_ || report_system_info_) {
         categories_to_probe.push_back(ProbeCategoryEnum::kSystem);
-        categories_to_probe.push_back(ProbeCategoryEnum::kSystem2);
       }
       if (report_storage_status_) {
         categories_to_probe.push_back(
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
index c36dee9..47363932 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
@@ -155,41 +155,35 @@
 constexpr char kFakeBatteryTechnology[] = "fake_battery_technology";
 constexpr char kFakeBatteryStatus[] = "fake_battery_status";
 // System test values:
-const char kFakeFirstPowerDate[] = "2020-40";
-const char kFakeManufactureDate[] = "2019-01-01";
-const char kFakeSkuNumber[] = "ABCD&^A";
-const char kFakeSerialNumber[] = "8607G03EDF";
-constexpr char kFakeSystemModelName[] = "XX ModelName 007 XY";
-constexpr char kFakeMarketingName[] = "Latitude 1234 Chromebook Enterprise";
-constexpr char kFakeBiosVersion[] = "Google_BoardName.12200.68.0";
-constexpr char kFakeBoardName[] = "BoardName";
-constexpr char kFakeBoardVersion[] = "rev1234";
-constexpr uint64_t kFakeChassisType = 9;
-constexpr char kFakeProductName[] = "ProductName";
-constexpr char kFakeVersionMilestone[] = "87";
-constexpr char kFakeVersionBuildNumber[] = "13544";
-constexpr char kFakeVersionPatchNumber[] = "59.0";
-constexpr char kFakeVersionReleaseChannel[] = "stable-channel";
-// System V2 test values:
-constexpr char kFakeOsInfoCodeName[] = "OsInfo Code Name";
-constexpr char kFakeOSInfoMarketingName[] = "OsInfo Marketing Name";
-constexpr char kFakeOSInfoOemName[] = "OsInfo OEM Name";
-constexpr cros_healthd::BootMode kFakeOsInfoBootMode =
-    cros_healthd::BootMode::kCrosSecure;
-constexpr em::BootInfo::BootMethod kFakeOsInfoBootMethod =
-    em::BootInfo::CROS_SECURE;
-constexpr char kFakeVpdInfoRegion[] = "VpdInfo Region";
 constexpr char kFakeDmiInfoBiosVendor[] = "DMI Bios Vendor";
-constexpr char kFakeDmiInfoBiosVersion[] = "DMI Bios Version";
+constexpr char kFakeDmiInfoBiosVersion[] = "Google_BoardName.12200.68.0";
 constexpr char kFakeDmiInfoBoardName[] = "DMI Board Name";
 constexpr char kFakeDmiInfoBoardVendor[] = "DMI Board Vendor";
-constexpr char kFakeDmiInfoBoardVersion[] = "DMI Board Version";
-constexpr char kFakeDmiInfoChassisVendor[] = "DMI Chassis Vendor";
+constexpr char kFakeDmiInfoBoardVersion[] = "rev1234";
 constexpr uint64_t kFakeDmiInfoChassisType = 9;
+constexpr char kFakeDmiInfoChassisVendor[] = "DMI Chassis Vendor";
 constexpr char kFakeDmiInfoProductFamily[] = "DMI Product Family";
-constexpr char kFakeDmiInfoSysVendor[] = "DMI System Vendor";
 constexpr char kFakeDmiInfoProductName[] = "DMI Product Name";
 constexpr char kFakeDmiInfoProductVersion[] = "DMI Product Version";
+constexpr char kFakeDmiInfoSysVendor[] = "DMI System Vendor";
+constexpr em::BootInfo::BootMethod kFakeOsInfoBootMethod =
+    em::BootInfo::CROS_SECURE;
+constexpr cros_healthd::BootMode kFakeOsInfoBootMode =
+    cros_healthd::BootMode::kCrosSecure;
+constexpr char kFakeOsInfoMarketingName[] =
+    "Latitude 1234 Chromebook Enterprise";
+constexpr char kFakeOsInfoOemName[] = "OsInfo OEM Name";
+constexpr char kFakeOsInfoProductName[] = "OsInfo Code Name";
+constexpr char kFakeOsVersionBuildNumber[] = "13544";
+constexpr char kFakeOsVersionMilestone[] = "87";
+constexpr char kFakeOsVersionPatchNumber[] = "59.0";
+constexpr char kFakeOsVersionReleaseChannel[] = "stable-channel";
+constexpr char kFakeVpdInfoFirstPowerDate[] = "2020-40";
+constexpr char kFakeVpdInfoManufactureDate[] = "2019-01-01";
+constexpr char kFakeVpdInfoRegion[] = "VpdInfo Region";
+constexpr char kFakeVpdInfoSerialNumber[] = "8607G03EDF";
+constexpr char kFakeVpdInfoSkuNumber[] = "ABCD&^A";
+constexpr char kFakeVpdInfoSystemModelName[] = "XX ModelName 007 XY";
 // CPU test values:
 constexpr uint32_t kFakeNumTotalThreads = 8;
 constexpr char kFakeModelName[] = "fake_cpu_model_name";
@@ -551,30 +545,19 @@
       std::move(storage_vector));
 }
 
-cros_healthd::SystemResultPtr CreateSystemResult() {
-  return cros_healthd::SystemResult::NewSystemInfo(
-      cros_healthd::SystemInfo::New(
-          kFakeFirstPowerDate, kFakeManufactureDate, kFakeSkuNumber,
-          kFakeSerialNumber, kFakeSystemModelName, kFakeMarketingName,
-          kFakeBiosVersion, kFakeBoardName, kFakeBoardVersion,
-          cros_healthd::NullableUint64::New(kFakeChassisType), kFakeProductName,
-          cros_healthd::OsVersion::New(
-              kFakeVersionMilestone, kFakeVersionBuildNumber,
-              kFakeVersionPatchNumber, kFakeVersionReleaseChannel)));
-}
-
 cros_healthd::SystemResultV2Ptr CreateSystemResultV2() {
   return cros_healthd::SystemResultV2::NewSystemInfoV2(
       cros_healthd::SystemInfoV2::New(
           cros_healthd::OsInfo::New(
-              kFakeOsInfoCodeName, kFakeOSInfoMarketingName,
+              kFakeOsInfoProductName, kFakeOsInfoMarketingName,
               cros_healthd::OsVersion::New(
-                  kFakeVersionMilestone, kFakeVersionBuildNumber,
-                  kFakeVersionPatchNumber, kFakeVersionReleaseChannel),
-              kFakeOsInfoBootMode, kFakeOSInfoOemName),
-          cros_healthd::VpdInfo::New(kFakeSerialNumber, kFakeVpdInfoRegion,
-                                     kFakeManufactureDate, kFakeFirstPowerDate,
-                                     kFakeSkuNumber, kFakeModelName),
+                  kFakeOsVersionMilestone, kFakeOsVersionBuildNumber,
+                  kFakeOsVersionPatchNumber, kFakeOsVersionReleaseChannel),
+              kFakeOsInfoBootMode, kFakeOsInfoOemName),
+          cros_healthd::VpdInfo::New(
+              kFakeVpdInfoSerialNumber, kFakeVpdInfoRegion,
+              kFakeVpdInfoManufactureDate, kFakeVpdInfoFirstPowerDate,
+              kFakeVpdInfoSkuNumber, kFakeVpdInfoSystemModelName),
           cros_healthd::DmiInfo::New(
               kFakeDmiInfoBiosVendor, kFakeDmiInfoBiosVersion,
               kFakeDmiInfoBoardName, kFakeDmiInfoBoardVendor,
@@ -721,7 +704,6 @@
       cros_healthd::TelemetryInfo fake_info;
       fake_info.battery_result = CreateBatteryResult();
       fake_info.block_device_result = CreateBlockDeviceResult();
-      fake_info.system_result = CreateSystemResult();
       fake_info.system_result_v2 = CreateSystemResultV2();
       fake_info.cpu_result = CreateCpuResult();
       fake_info.timezone_result = CreateTimezoneResult();
@@ -3449,19 +3431,24 @@
   // Verify the system info.
   ASSERT_TRUE(device_status_.has_system_status());
   EXPECT_EQ(device_status_.system_status().first_power_date(),
-            kFakeFirstPowerDate);
+            kFakeVpdInfoFirstPowerDate);
   EXPECT_EQ(device_status_.system_status().manufacture_date(),
-            kFakeManufactureDate);
-  EXPECT_EQ(device_status_.system_status().vpd_sku_number(), kFakeSkuNumber);
+            kFakeVpdInfoManufactureDate);
+  EXPECT_EQ(device_status_.system_status().vpd_sku_number(),
+            kFakeVpdInfoSkuNumber);
   EXPECT_EQ(device_status_.system_status().vpd_serial_number(),
-            kFakeSerialNumber);
+            kFakeVpdInfoSerialNumber);
   EXPECT_EQ(device_status_.system_status().marketing_name(),
-            kFakeMarketingName);
-  EXPECT_EQ(device_status_.system_status().bios_version(), kFakeBiosVersion);
-  EXPECT_EQ(device_status_.system_status().board_name(), kFakeBoardName);
-  EXPECT_EQ(device_status_.system_status().board_version(), kFakeBoardVersion);
-  EXPECT_EQ(device_status_.system_status().chassis_type(), kFakeChassisType);
-  EXPECT_EQ(device_status_.system_status().product_name(), kFakeProductName);
+            kFakeOsInfoMarketingName);
+  EXPECT_EQ(device_status_.system_status().bios_version(),
+            kFakeDmiInfoBiosVersion);
+  EXPECT_EQ(device_status_.system_status().board_name(), kFakeDmiInfoBoardName);
+  EXPECT_EQ(device_status_.system_status().board_version(),
+            kFakeDmiInfoBoardVersion);
+  EXPECT_EQ(device_status_.system_status().chassis_type(),
+            kFakeDmiInfoChassisType);
+  EXPECT_EQ(device_status_.system_status().product_name(),
+            kFakeOsInfoProductName);
 
   // Verify the system v2 info.
   ASSERT_TRUE(device_status_.has_smbios_info());
@@ -3658,12 +3645,13 @@
   // Verify the only vpd info is populated.
   ASSERT_TRUE(device_status_.has_system_status());
   EXPECT_EQ(device_status_.system_status().first_power_date(),
-            kFakeFirstPowerDate);
+            kFakeVpdInfoFirstPowerDate);
   EXPECT_EQ(device_status_.system_status().manufacture_date(),
-            kFakeManufactureDate);
-  EXPECT_EQ(device_status_.system_status().vpd_sku_number(), kFakeSkuNumber);
+            kFakeVpdInfoManufactureDate);
+  EXPECT_EQ(device_status_.system_status().vpd_sku_number(),
+            kFakeVpdInfoSkuNumber);
   EXPECT_EQ(device_status_.system_status().vpd_serial_number(),
-            kFakeSerialNumber);
+            kFakeVpdInfoSerialNumber);
   ASSERT_FALSE(device_status_.system_status().has_marketing_name());
   ASSERT_FALSE(device_status_.system_status().has_bios_version());
   ASSERT_FALSE(device_status_.system_status().has_board_name());
@@ -3695,12 +3683,16 @@
   ASSERT_FALSE(device_status_.system_status().has_manufacture_date());
   ASSERT_FALSE(device_status_.system_status().has_vpd_sku_number());
   EXPECT_EQ(device_status_.system_status().marketing_name(),
-            kFakeMarketingName);
-  EXPECT_EQ(device_status_.system_status().bios_version(), kFakeBiosVersion);
-  EXPECT_EQ(device_status_.system_status().board_name(), kFakeBoardName);
-  EXPECT_EQ(device_status_.system_status().board_version(), kFakeBoardVersion);
-  EXPECT_EQ(device_status_.system_status().chassis_type(), kFakeChassisType);
-  EXPECT_EQ(device_status_.system_status().product_name(), kFakeProductName);
+            kFakeOsInfoMarketingName);
+  EXPECT_EQ(device_status_.system_status().bios_version(),
+            kFakeDmiInfoBiosVersion);
+  EXPECT_EQ(device_status_.system_status().board_name(), kFakeDmiInfoBoardName);
+  EXPECT_EQ(device_status_.system_status().board_version(),
+            kFakeDmiInfoBoardVersion);
+  EXPECT_EQ(device_status_.system_status().chassis_type(),
+            kFakeDmiInfoChassisType);
+  EXPECT_EQ(device_status_.system_status().product_name(),
+            kFakeOsInfoProductName);
 
   // Verify system info V2 exists too.
   ASSERT_TRUE(device_status_.has_smbios_info());
diff --git a/chrome/browser/ash/system_extensions/api/window_management/BUILD.gn b/chrome/browser/ash/system_extensions/api/window_management/BUILD.gn
index a9de1da3a2..1d479b7 100644
--- a/chrome/browser/ash/system_extensions/api/window_management/BUILD.gn
+++ b/chrome/browser/ash/system_extensions/api/window_management/BUILD.gn
@@ -8,6 +8,10 @@
 
 source_set("window_management") {
   sources = [
+    "cros_window_management_context.cc",
+    "cros_window_management_context.h",
+    "cros_window_management_context_factory.cc",
+    "cros_window_management_context_factory.h",
     "window_management_impl.cc",
     "window_management_impl.h",
   ]
@@ -20,7 +24,9 @@
 
   deps = [
     "//ash",
+    "//chrome/browser/ash/system_extensions",
     "//chrome/browser/profiles:profile",
+    "//components/keyed_service/content",
     "//components/services/app_service/public/cpp:instance_update",
     "//components/services/app_service/public/mojom",
     "//content/public/browser",
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
index 7ba0d79..be68c55 100644
--- a/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_browsertest.cc
@@ -826,8 +826,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CrosWindowExtensionBrowserTest, StartEvent) {
-  auto* provider = SystemExtensionsProvider::Get(browser()->profile());
-  auto& install_manager = provider->install_manager();
+  auto& provider = SystemExtensionsProvider::Get(browser()->profile());
+  auto& install_manager = provider.install_manager();
 
   // TODO(b/230811571): Rather than using the console to wait for the
   // observer to get called, we should add support for running async functions
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.cc
new file mode 100644
index 0000000..a2ad9416
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.cc
@@ -0,0 +1,21 @@
+// 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/system_extensions/api/window_management/cros_window_management_context.h"
+
+#include "chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h"
+
+namespace ash {
+
+// static
+CrosWindowManagementContext& CrosWindowManagementContext::Get(
+    Profile* profile) {
+  return *CrosWindowManagementContextFactory::GetForProfileIfExists(profile);
+}
+
+CrosWindowManagementContext::CrosWindowManagementContext() = default;
+
+CrosWindowManagementContext::~CrosWindowManagementContext() = default;
+
+}  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.h b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.h
new file mode 100644
index 0000000..93b86ff
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.h
@@ -0,0 +1,32 @@
+// 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_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_H_
+#define CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_H_
+
+#include "components/keyed_service/core/keyed_service.h"
+
+class Profile;
+
+namespace ash {
+
+// Class in charge of managing CrosWindowManagement instances and dispatching
+// events to them.
+class CrosWindowManagementContext : public KeyedService {
+ public:
+  // Returns the event dispatcher associated with `profile`. Should only be
+  // called if System Extensions is enabled for the profile i.e. if
+  // IsSystemExtensionsEnabled() returns true.
+  static CrosWindowManagementContext& Get(Profile* profile);
+
+  CrosWindowManagementContext();
+  CrosWindowManagementContext(const CrosWindowManagementContext&) = delete;
+  CrosWindowManagementContext& operator=(const CrosWindowManagementContext&) =
+      delete;
+  ~CrosWindowManagementContext() override;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_H_
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.cc b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.cc
new file mode 100644
index 0000000..3407d927
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.cc
@@ -0,0 +1,55 @@
+// 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/system_extensions/api/window_management/cros_window_management_context_factory.h"
+
+#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace ash {
+
+// static
+CrosWindowManagementContext*
+CrosWindowManagementContextFactory::GetForProfileIfExists(Profile* profile) {
+  return static_cast<CrosWindowManagementContext*>(
+      CrosWindowManagementContextFactory::GetInstance()
+          .GetServiceForBrowserContext(profile, /*create=*/false));
+}
+
+// static
+CrosWindowManagementContextFactory&
+CrosWindowManagementContextFactory::GetInstance() {
+  static base::NoDestructor<CrosWindowManagementContextFactory> instance;
+  return *instance;
+}
+
+CrosWindowManagementContextFactory::CrosWindowManagementContextFactory()
+    : BrowserContextKeyedServiceFactory(
+          "CrosWindowManagementContextFactory",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+CrosWindowManagementContextFactory::~CrosWindowManagementContextFactory() =
+    default;
+
+KeyedService* CrosWindowManagementContextFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return nullptr;
+}
+
+bool CrosWindowManagementContextFactory::ServiceIsCreatedWithBrowserContext()
+    const {
+  return true;
+}
+
+content::BrowserContext*
+CrosWindowManagementContextFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return GetProfileForSystemExtensions(Profile::FromBrowserContext(context));
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h
new file mode 100644
index 0000000..2ef68e7
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h
@@ -0,0 +1,49 @@
+// 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_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_FACTORY_H_
+#define CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace ash {
+
+class CrosWindowManagementContext;
+
+// Class to retrieve the CrosWindowManagementContext associated with
+// a profile.
+class CrosWindowManagementContextFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  static CrosWindowManagementContextFactory& GetInstance();
+
+  // CrosWindowManagementContext is created automatically for
+  // appropriate profiles e.g. the primary profile.
+  static CrosWindowManagementContext* GetForProfileIfExists(Profile* profile);
+
+  CrosWindowManagementContextFactory(
+      const CrosWindowManagementContextFactory&) = delete;
+  CrosWindowManagementContextFactory& operator=(
+      const CrosWindowManagementContextFactory&) = delete;
+
+ private:
+  friend base::NoDestructor<CrosWindowManagementContextFactory>;
+
+  CrosWindowManagementContextFactory();
+  ~CrosWindowManagementContextFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_API_WINDOW_MANAGEMENT_CROS_WINDOW_MANAGEMENT_CONTEXT_FACTORY_H_
diff --git a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
index 424a820..80fab9e 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
@@ -99,8 +99,8 @@
   ~SystemExtensionsBrowserTest() override = default;
 
   void TestInstalledTestExtensionWorks() {
-    auto* provider = SystemExtensionsProvider::Get(browser()->profile());
-    auto& install_manager = provider->install_manager();
+    auto& provider = SystemExtensionsProvider::Get(browser()->profile());
+    auto& install_manager = provider.install_manager();
 
     auto extension_ids = install_manager.GetSystemExtensionIds();
     EXPECT_EQ(std::vector<SystemExtensionId>({kTestSystemExtensionId}),
@@ -152,10 +152,10 @@
 }  // namespace
 
 IN_PROC_BROWSER_TEST_F(SystemExtensionsBrowserTest, InstallFromDir_Success) {
-  auto* provider = SystemExtensionsProvider::Get(browser()->profile());
-  auto& install_manager = provider->install_manager();
+  auto& provider = SystemExtensionsProvider::Get(browser()->profile());
+  auto& install_manager = provider.install_manager();
 
-  ServiceWorkerRegistrationObserver sw_registration_observer(*provider);
+  ServiceWorkerRegistrationObserver sw_registration_observer(provider);
   base::RunLoop run_loop;
   install_manager.InstallUnpackedExtensionFromDir(
       GetBasicSystemExtensionDir(),
@@ -174,8 +174,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SystemExtensionsSwitchBrowserTest, ExtensionInstalled) {
-  auto* provider = SystemExtensionsProvider::Get(browser()->profile());
-  auto& install_manager = provider->install_manager();
+  auto& provider = SystemExtensionsProvider::Get(browser()->profile());
+  auto& install_manager = provider.install_manager();
 
   base::RunLoop run_loop;
   install_manager.on_command_line_install_finished().Post(
diff --git a/chrome/browser/ash/system_extensions/system_extensions_internals_page_handler.cc b/chrome/browser/ash/system_extensions/system_extensions_internals_page_handler.cc
index 6b2c942..d93b351 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_internals_page_handler.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_internals_page_handler.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/system_extensions/system_extensions_internals_page_handler.h"
 
 #include "base/debug/stack_trace.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 
 namespace ash {
 
@@ -21,6 +22,11 @@
     InstallSystemExtensionFromDownloadsDir(
         const base::SafeBaseName& system_extension_dir_name,
         InstallSystemExtensionFromDownloadsDirCallback callback) {
+  if (!IsSystemExtensionsEnabled(profile_)) {
+    std::move(callback).Run(false);
+    return;
+  }
+
   base::FilePath downloads_path;
   if (!base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE,
                               &downloads_path)) {
@@ -29,7 +35,7 @@
   }
 
   auto& install_manager =
-      SystemExtensionsProvider::Get(profile_)->install_manager();
+      SystemExtensionsProvider::Get(profile_).install_manager();
   base::FilePath system_extension_dir =
       downloads_path.Append(system_extension_dir_name);
 
diff --git a/chrome/browser/ash/system_extensions/system_extensions_profile_utils.cc b/chrome/browser/ash/system_extensions/system_extensions_profile_utils.cc
index 1db5f1a4..8154767 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_profile_utils.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_profile_utils.cc
@@ -4,13 +4,50 @@
 
 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 
+#include "ash/constants/ash_features.h"
 #include "base/files/file_path.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
+#include "components/user_manager/user_manager.h"
 
 namespace ash {
 
 constexpr char kSystemExtensionsProfileDirectory[] = "SystemExtensions";
 
+bool IsSystemExtensionsEnabled(Profile* profile) {
+  return !!GetProfileForSystemExtensions(profile);
+}
+
+Profile* GetProfileForSystemExtensions(Profile* profile) {
+  if (!base::FeatureList::IsEnabled(ash::features::kSystemExtensions))
+    return nullptr;
+
+  // Enable System Extensions on the primary profile only for now. As we
+  // implement new System Extension types we will enable the provider on other
+  // profiles.
+  if (profile->IsOffTheRecord())
+    return nullptr;
+
+  if (profile->IsSystemProfile())
+    return nullptr;
+
+  if (!ash::ProfileHelper::IsRegularProfile(profile))
+    return nullptr;
+
+  if (!ash::ProfileHelper::IsPrimaryProfile(profile))
+    return nullptr;
+
+  auto* user_manager = user_manager::UserManager::Get();
+  if (user_manager && user_manager->IsLoggedInAsAnyKioskApp())
+    return nullptr;
+
+  if (profile->IsGuestSession())
+    return nullptr;
+
+  return profile;
+}
+
 base::FilePath GetDirectoryForSystemExtension(Profile& profile,
                                               const SystemExtensionId& id) {
   return GetSystemExtensionsProfileDir(profile).Append(
diff --git a/chrome/browser/ash/system_extensions/system_extensions_profile_utils.h b/chrome/browser/ash/system_extensions/system_extensions_profile_utils.h
index faef7fa..3690b5ba 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_profile_utils.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_profile_utils.h
@@ -15,6 +15,14 @@
 
 namespace ash {
 
+// Returns true if System Extensions is enabled for the profile, including
+// if the System Extensions feature flag is enabled.
+bool IsSystemExtensionsEnabled(Profile* profile);
+
+// Finds which Profile, if any, to use for System Extensions. Returns nullptr if
+// System Extensions should not be enabled for the profile.
+Profile* GetProfileForSystemExtensions(Profile* profile);
+
 base::FilePath GetDirectoryForSystemExtension(Profile& profile,
                                               const SystemExtensionId& id);
 
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider.cc b/chrome/browser/ash/system_extensions/system_extensions_provider.cc
index 5e19a40c..b83bf80 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "chrome/browser/ash/system_extensions/system_extension.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_install_manager.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider_factory.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/url_constants.h"
@@ -21,13 +22,9 @@
 const char* kSystemExtensionScheme = content::kChromeUIUntrustedScheme;
 
 // static
-SystemExtensionsProvider* SystemExtensionsProvider::Get(Profile* profile) {
-  return SystemExtensionsProviderFactory::GetForProfileIfExists(profile);
-}
-
-// static
-bool SystemExtensionsProvider::IsEnabled() {
-  return base::FeatureList::IsEnabled(ash::features::kSystemExtensions);
+SystemExtensionsProvider& SystemExtensionsProvider::Get(Profile* profile) {
+  DCHECK(ash::IsSystemExtensionsEnabled(profile));
+  return *SystemExtensionsProviderFactory::GetForProfileIfExists(profile);
 }
 
 // static
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider.h b/chrome/browser/ash/system_extensions/system_extensions_provider.h
index 2b724a4..b77f4265 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider.h
@@ -22,9 +22,10 @@
 // Manages the installation, storage, and execution of System Extensions.
 class SystemExtensionsProvider : public KeyedService {
  public:
-  // May return nullptr if there is no provider associated with this profile.
-  static SystemExtensionsProvider* Get(Profile* profile);
-  static bool IsEnabled();
+  // Returns the provider associated with `profile`. Should only be called if
+  // System Extensions is enabled for the profile i.e. if
+  // IsSystemExtensionsEnabled() returns true.
+  static SystemExtensionsProvider& Get(Profile* profile);
 
   // TODO(crbug.com/1272371): Remove when APIs can be accessed in a less hacky
   // way.
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
index eaf8b12..e1a8796 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
@@ -6,6 +6,7 @@
 
 #include "base/no_destructor.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
@@ -49,28 +50,7 @@
 content::BrowserContext*
 SystemExtensionsProviderFactory::GetBrowserContextToUse(
     content::BrowserContext* context) const {
-  DCHECK(context);
-  // Enable System Extensions on the primary profile only for now. As we
-  // implement new System Extension types we will enable the provider on other
-  // profiles.
-  Profile* const profile = Profile::FromBrowserContext(context);
-  if (profile->IsSystemProfile())
-    return nullptr;
-
-  if (!ash::ProfileHelper::IsRegularProfile(profile))
-    return nullptr;
-
-  if (!ash::ProfileHelper::IsPrimaryProfile(profile))
-    return nullptr;
-
-  auto* user_manager = user_manager::UserManager::Get();
-  if (user_manager && user_manager->IsLoggedInAsAnyKioskApp())
-    return nullptr;
-
-  if (profile->IsGuestSession())
-    return nullptr;
-
-  return BrowserContextKeyedServiceFactory::GetBrowserContextToUse(context);
+  return GetProfileForSystemExtensions(Profile::FromBrowserContext(context));
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
index cd0dd24c..dd1168c 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
@@ -29,14 +29,15 @@
 
   static SystemExtensionsProviderFactory& GetInstance();
 
- private:
-  friend base::NoDestructor<SystemExtensionsProviderFactory>;
-
-  SystemExtensionsProviderFactory();
   SystemExtensionsProviderFactory(const SystemExtensionsProviderFactory&) =
       delete;
   SystemExtensionsProviderFactory& operator=(
       const SystemExtensionsProviderFactory&) = delete;
+
+ private:
+  friend base::NoDestructor<SystemExtensionsProviderFactory>;
+
+  SystemExtensionsProviderFactory();
   ~SystemExtensionsProviderFactory() override;
 
   // BrowserContextKeyedServiceFactory:
diff --git a/chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h b/chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h
index 106f5503..a3ad99f 100644
--- a/chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h
+++ b/chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h
@@ -171,7 +171,7 @@
   // aborted.
   //
   // This is implemented in
-  // chrome/browser/ui/web_applications/system_web_app_delegate_ui_impl.cc.
+  // chrome/browser/ui/ash/system_web_apps/system_web_app_delegate_ui_impl.cc.
   virtual Browser* LaunchAndNavigateSystemWebApp(
       Profile* profile,
       web_app::WebAppProvider* provider,
diff --git a/chrome/browser/ash/usb/cros_usb_detector.cc b/chrome/browser/ash/usb/cros_usb_detector.cc
index 6a354c8..39dfc93 100644
--- a/chrome/browser/ash/usb/cros_usb_detector.cc
+++ b/chrome/browser/ash/usb/cros_usb_detector.cc
@@ -550,7 +550,9 @@
 }
 
 void CrosUsbDetector::OnVmStopped(
-    const vm_tools::concierge::VmStoppedSignal& signal) {}
+    const vm_tools::concierge::VmStoppedSignal& signal) {
+  DisconnectSharedDevicesOnVmShutdown(signal.name());
+}
 
 void CrosUsbDetector::OnVmToolsStateChanged(
     const vm_tools::plugin_dispatcher::VmToolsStateChangedSignal& signal) {}
@@ -560,6 +562,9 @@
   if (signal.vm_state() ==
       vm_tools::plugin_dispatcher::VmState::VM_STATE_RUNNING) {
     ConnectSharedDevicesOnVmStartup(signal.vm_name());
+  } else if (signal.vm_state() ==
+             vm_tools::plugin_dispatcher::VmState::VM_STATE_STOPPED) {
+    DisconnectSharedDevicesOnVmShutdown(signal.vm_name());
   }
 }
 
@@ -714,6 +719,18 @@
   }
 }
 
+void CrosUsbDetector::DisconnectSharedDevicesOnVmShutdown(
+    const std::string& vm_name) {
+  // Clear guest_port on shared devices when the VM shuts down.
+  for (auto& it : usb_devices_) {
+    auto& device = it.second;
+    if (device.shared_vm_name == vm_name) {
+      VLOG(1) << device.label << " is disconnected from " << vm_name;
+      device.guest_port = absl::nullopt;
+    }
+  }
+}
+
 void CrosUsbDetector::AttachUsbDeviceToVm(
     const std::string& vm_name,
     const std::string& guid,
diff --git a/chrome/browser/ash/usb/cros_usb_detector.h b/chrome/browser/ash/usb/cros_usb_detector.h
index 8a7ebad..ff5e8b8 100644
--- a/chrome/browser/ash/usb/cros_usb_detector.h
+++ b/chrome/browser/ash/usb/cros_usb_detector.h
@@ -99,6 +99,8 @@
   // Called when a VM starts, to attach USB devices marked as shared to the VM.
   void ConnectSharedDevicesOnVmStartup(const std::string& vm_name);
 
+  void DisconnectSharedDevicesOnVmShutdown(const std::string& vm_name);
+
   // device::mojom::UsbDeviceManagerClient
   void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device) override;
   void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device) override;
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
index 90a1576e..37d2a9a 100644
--- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_integration_browsertest.cc
@@ -194,7 +194,7 @@
     ash::WallpaperController::Get()->SetCustomWallpaper(
         user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
         /*file_name=*/"fakename", ash::WALLPAPER_LAYOUT_CENTER_CROPPED, image,
-        /*preview_mode=*/true);
+        /*preview_mode=*/true, /*file_path=*/"");
 
     loop.Run();
   }
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 6f3e2d4..e7600e6d 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
@@ -381,12 +381,14 @@
     case ash::WallpaperType::kCustomized: {
       base::FilePath file_name = base::FilePath(info.location).BaseName();
 
-      // Match selected wallpaper based on full filename including extension.
-      const std::string& key = file_name.value();
       // Do not show file extension in user-visible selected details text.
       std::vector<std::string> attribution = {
           file_name.RemoveExtension().value()};
 
+      // Match selected wallpaper based on full filename including extension.
+      const std::string& key =
+          info.user_file_path.empty() ? file_name.value() : info.user_file_path;
+
       NotifyWallpaperChanged(
           ash::personalization_app::mojom::CurrentWallpaper::New(
               wallpaper_data_url, std::move(attribution), info.layout,
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index 282c5aa6..2e15b10 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -264,7 +264,8 @@
 
   // AutocompleteProviderListener:
   // If we're waiting for the provider to finish, this exits the message loop.
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   // Runs a nested run loop until provider_ is done. The message loop is
   // exited by way of OnProviderUpdate.
@@ -462,7 +463,9 @@
   }
 }
 
-void BaseSearchProviderTest::OnProviderUpdate(bool updated_matches) {
+void BaseSearchProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   if (run_loop_ && provider_->done()) {
     run_loop_->Quit();
     run_loop_ = nullptr;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 4c44b21..c12c0bc 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -367,6 +367,7 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/smb_client/fileapi/smbfs_file_system_backend_delegate.h"
 #include "chrome/browser/ash/system/input_device_settings.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
 #include "chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h"
 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
@@ -2673,14 +2674,12 @@
   DCHECK(context);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (!ash::SystemExtensionsProvider::IsEnabled())
+  auto* profile = Profile::FromBrowserContext(context);
+  if (!ash::IsSystemExtensionsEnabled(profile))
     return;
 
-  auto* system_extensions_provider =
-      ash::SystemExtensionsProvider::Get(Profile::FromBrowserContext(context));
-  if (system_extensions_provider)
-    system_extensions_provider->WillStartServiceWorker(script_url,
-                                                       render_process_host);
+  ash::SystemExtensionsProvider::Get(profile).WillStartServiceWorker(
+      script_url, render_process_host);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 64aadc1c..b6a8162e 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -461,6 +461,7 @@
   void RegisterMojoBinderPoliciesForSameOriginPrerendering(
       content::MojoBinderPolicyMap& policy_map) override;
   void RegisterBrowserInterfaceBindersForServiceWorker(
+      content::BrowserContext* browser_context,
       mojo::BinderMapWithContext<const content::ServiceWorkerVersionBaseInfo&>*
           map) override;
   void RegisterAssociatedInterfaceBindersForRenderFrameHost(
diff --git a/chrome/browser/chrome_content_browser_client_receiver_bindings.cc b/chrome/browser/chrome_content_browser_client_receiver_bindings.cc
index 5b8e9f3..61eb034 100644
--- a/chrome/browser/chrome_content_browser_client_receiver_bindings.cc
+++ b/chrome/browser/chrome_content_browser_client_receiver_bindings.cc
@@ -59,6 +59,7 @@
 #include "chrome/browser/ash/system_extensions/api/hid/hid_impl.h"
 #include "chrome/browser/ash/system_extensions/api/window_management/window_management_impl.h"
 #include "chrome/browser/ash/system_extensions/system_extension.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
 #include "chromeos/components/cdm_factory_daemon/cdm_factory_daemon_proxy_ash.h"
 #include "components/performance_manager/public/performance_manager.h"
@@ -340,6 +341,7 @@
 
 void ChromeContentBrowserClient::
     RegisterBrowserInterfaceBindersForServiceWorker(
+        content::BrowserContext* browser_context,
         mojo::BinderMapWithContext<
             const content::ServiceWorkerVersionBaseInfo&>* map) {
 #if !BUILDFLAG(IS_ANDROID)
@@ -350,7 +352,8 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // TODO(crbug.com/1253318): Only add this mapping if the System Extension type
   // is Window Manager.
-  if (ash::SystemExtensionsProvider::IsEnabled()) {
+  auto* profile = Profile::FromBrowserContext(browser_context);
+  if (ash::IsSystemExtensionsEnabled(profile)) {
     map->Add<blink::mojom::CrosWindowManagement>(base::BindRepeating(
         [](const content::ServiceWorkerVersionBaseInfo& info,
            mojo::PendingReceiver<blink::mojom::CrosWindowManagement> receiver) {
@@ -376,12 +379,10 @@
               std::move(receiver));
         }));
   }
-#endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   // TODO(b/210738172): Only add this mapping if the System Extension type
   // is HID.
-  if (ash::SystemExtensionsProvider::IsEnabled()) {
+  if (ash::IsSystemExtensionsEnabled(profile)) {
     map->Add<blink::mojom::CrosHID>(base::BindRepeating(
         [](const content::ServiceWorkerVersionBaseInfo& info,
            mojo::PendingReceiver<blink::mojom::CrosHID> receiver) {
@@ -406,7 +407,7 @@
                                       std::move(receiver));
         }));
   }
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void ChromeContentBrowserClient::
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index a8edb364..dc1a9d3 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -262,6 +262,7 @@
     "//chromeos/ash/components/dbus/fusebox",
     "//chromeos/ash/components/dbus/fusebox:proto",
     "//chromeos/ash/components/dbus/human_presence",
+    "//chromeos/ash/components/dbus/image_loader",
     "//chromeos/ash/components/dbus/ip_peripheral",
     "//chromeos/ash/components/dbus/kerberos",
     "//chromeos/ash/components/dbus/kerberos:kerberos_proto",
@@ -343,7 +344,6 @@
     "//chromeos/dbus/fwupd",
     "//chromeos/dbus/gnubby",
     "//chromeos/dbus/hermes",
-    "//chromeos/dbus/image_loader",
     "//chromeos/dbus/machine_learning",
     "//chromeos/dbus/missive",
     "//chromeos/dbus/permission_broker",
@@ -1398,6 +1398,8 @@
     "../ash/policy/reporting/metrics_reporting/metric_reporting_manager.h",
     "../ash/policy/reporting/metrics_reporting/network/https_latency_sampler.cc",
     "../ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h",
+    "../ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.cc",
+    "../ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler.h",
     "../ash/policy/reporting/metrics_reporting/network/network_events_observer.cc",
     "../ash/policy/reporting/metrics_reporting/network/network_events_observer.h",
     "../ash/policy/reporting/metrics_reporting/network/network_info_sampler.cc",
@@ -2502,6 +2504,8 @@
     "../ash/borealis/testing/features.h",
     "../ash/borealis/testing/widgets.cc",
     "../ash/borealis/testing/widgets.h",
+    "../ash/bruschetta/fake_bruschetta_features.cc",
+    "../ash/bruschetta/fake_bruschetta_features.h",
     "../ash/cert_provisioning/mock_cert_provisioning_invalidator.cc",
     "../ash/cert_provisioning/mock_cert_provisioning_invalidator.h",
     "../ash/cert_provisioning/mock_cert_provisioning_scheduler.cc",
@@ -2518,6 +2522,8 @@
     "../ash/crostini/crostini_test_util.h",
     "../ash/crostini/fake_crostini_features.cc",
     "../ash/crostini/fake_crostini_features.h",
+    "../ash/crostini/fake_crostini_installer_ui_delegate.cc",
+    "../ash/crostini/fake_crostini_installer_ui_delegate.h",
     "../ash/device_name/fake_device_name_applier.cc",
     "../ash/device_name/fake_device_name_applier.h",
     "../ash/device_name/fake_device_name_store.cc",
@@ -3270,6 +3276,7 @@
     "../ash/policy/reporting/metrics_reporting/cros_reporting_settings_unittest.cc",
     "../ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc",
     "../ash/policy/reporting/metrics_reporting/network/https_latency_sampler_unittest.cc",
+    "../ash/policy/reporting/metrics_reporting/network/network_bandwidth_sampler_unittest.cc",
     "../ash/policy/reporting/metrics_reporting/network/network_events_observer_unittest.cc",
     "../ash/policy/reporting/metrics_reporting/network/network_info_sampler_unittest.cc",
     "../ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc",
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
index 7be7620f..63c9909 100644
--- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc
+++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -20,8 +20,8 @@
 #include "chrome/browser/component_updater/component_installer_errors.h"
 #include "chrome/browser/component_updater/metadata_table_chromeos.h"
 #include "chrome/common/pref_names.h"
+#include "chromeos/ash/components/dbus/image_loader/image_loader_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/image_loader/image_loader_client.h"
 #include "components/component_updater/component_updater_paths.h"
 #include "components/crx_file/id_util.h"
 #include "components/prefs/pref_service.h"
@@ -85,7 +85,7 @@
 void FinishCustomUninstallOnUIThread(const std::string& name) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  chromeos::ImageLoaderClient::Get()->UnmountComponent(
+  ash::ImageLoaderClient::Get()->UnmountComponent(
       name, base::BindOnce(&LogCustomUninstall));
 }
 
@@ -481,7 +481,7 @@
 
   const base::FilePath path = GetCompatiblePath(name);
   DCHECK(!path.empty());
-  chromeos::ImageLoaderClient::Get()->LoadComponentAtPath(
+  ash::ImageLoaderClient::Get()->LoadComponentAtPath(
       name, path,
       base::BindOnce(&CrOSComponentInstaller::FinishLoad,
                      base::Unretained(this), std::move(load_callback),
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc b/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc
index f3cb830..7869b1c66 100644
--- a/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc
+++ b/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc
@@ -25,9 +25,9 @@
 #include "chrome/browser/component_updater/metadata_table_chromeos.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h"
+#include "chromeos/ash/components/dbus/image_loader/image_loader_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/image_loader/fake_image_loader_client.h"
-#include "chromeos/dbus/image_loader/image_loader_client.h"
 #include "components/component_updater/mock_component_updater_service.h"
 #include "components/update_client/utils.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -212,14 +212,14 @@
     tmp_unpack_dir_ = base_component_paths_.GetPath().AppendASCII("tmp_unpack");
 
     chromeos::DBusThreadManager::Initialize();
-    chromeos::ImageLoaderClient::InitializeFake();
-    image_loader_client_ = static_cast<chromeos::FakeImageLoaderClient*>(
-        chromeos::ImageLoaderClient::Get());
+    ash::ImageLoaderClient::InitializeFake();
+    image_loader_client_ =
+        static_cast<ash::FakeImageLoaderClient*>(ash::ImageLoaderClient::Get());
   }
 
   void TearDown() override {
     image_loader_client_ = nullptr;
-    chromeos::ImageLoaderClient::Shutdown();
+    ash::ImageLoaderClient::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
     preinstalled_components_path_override_.reset();
     user_components_path_override_.reset();
@@ -298,7 +298,7 @@
 
   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
 
-  chromeos::FakeImageLoaderClient* image_loader_client() {
+  ash::FakeImageLoaderClient* image_loader_client() {
     return image_loader_client_;
   }
 
@@ -352,7 +352,7 @@
   user_manager::ScopedUserManager user_manager_;
 
   // Image loader client that is active during the test.
-  chromeos::FakeImageLoaderClient* image_loader_client_ = nullptr;
+  ash::FakeImageLoaderClient* image_loader_client_ = nullptr;
 
   base::ScopedTempDir base_component_paths_;
 
diff --git a/chrome/browser/extensions/api/offscreen/offscreen_apitest.cc b/chrome/browser/extensions/api/offscreen/offscreen_apitest.cc
index 369b60a..75f466e 100644
--- a/chrome/browser/extensions/api/offscreen/offscreen_apitest.cc
+++ b/chrome/browser/extensions/api/offscreen/offscreen_apitest.cc
@@ -36,8 +36,9 @@
 };
 
 // Tests the general flow of creating an offscreen document.
-IN_PROC_BROWSER_TEST_F(OffscreenApiTest, CreateDocument) {
-  ASSERT_TRUE(RunExtensionTest("offscreen/create_document")) << message_;
+IN_PROC_BROWSER_TEST_F(OffscreenApiTest, BasicDocumentManagement) {
+  ASSERT_TRUE(RunExtensionTest("offscreen/basic_document_management"))
+      << message_;
 }
 
 class OffscreenApiTestWithoutFeature : public ExtensionApiTest {
diff --git a/chrome/browser/extensions/api/offscreen/offscreen_document_manager_browsertest.cc b/chrome/browser/extensions/api/offscreen/offscreen_document_manager_browsertest.cc
index 9b787ce..c8eb402 100644
--- a/chrome/browser/extensions/api/offscreen/offscreen_document_manager_browsertest.cc
+++ b/chrome/browser/extensions/api/offscreen/offscreen_document_manager_browsertest.cc
@@ -235,4 +235,81 @@
                 *extension));
 }
 
+// Tests the flow of closing an existing offscreen document through the
+// manager.
+IN_PROC_BROWSER_TEST_F(OffscreenDocumentManagerBrowserTest,
+                       ClosingDocumentThroughTheManager) {
+  static constexpr char kManifest[] =
+      R"({
+           "name": "Offscreen Document Test",
+           "manifest_version": 3,
+           "version": "0.1"
+         })";
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifest);
+  test_dir.WriteFile(FILE_PATH_LITERAL("offscreen.html"),
+                     "<html>offscreen</html>");
+
+  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
+  ASSERT_TRUE(extension);
+
+  const GURL offscreen_url = extension->GetResourceURL("offscreen.html");
+
+  OffscreenDocumentHost* offscreen_document =
+      CreateDocumentAndWaitForLoad(*extension, offscreen_url);
+  ASSERT_TRUE(offscreen_document);
+
+  {
+    ExtensionHostTestHelper host_waiter(profile());
+    host_waiter.RestrictToHost(offscreen_document);
+    offscreen_document_manager()->CloseOffscreenDocumentForExtension(
+        *extension);
+  }
+
+  EXPECT_EQ(nullptr,
+            offscreen_document_manager()->GetOffscreenDocumentForExtension(
+                *extension));
+}
+
+// Tests calling window.close() in an offscreen document closes it (through the
+// manager).
+IN_PROC_BROWSER_TEST_F(OffscreenDocumentManagerBrowserTest,
+                       CallingWindowCloseInAnOffscreenDocumentClosesIt) {
+  static constexpr char kManifest[] =
+      R"({
+           "name": "Offscreen Document Test",
+           "manifest_version": 3,
+           "version": "0.1"
+         })";
+  TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifest);
+  test_dir.WriteFile(FILE_PATH_LITERAL("offscreen.html"),
+                     "<html>offscreen</html>");
+
+  scoped_refptr<const Extension> extension =
+      LoadExtension(test_dir.UnpackedPath());
+  ASSERT_TRUE(extension);
+
+  OffscreenDocumentHost* offscreen_document = CreateDocumentAndWaitForLoad(
+      *extension, extension->GetResourceURL("offscreen.html"));
+  ASSERT_TRUE(offscreen_document);
+  EXPECT_EQ(offscreen_document,
+            offscreen_document_manager()->GetOffscreenDocumentForExtension(
+                *extension));
+
+  {
+    // Call window.close() from the offscreen document. This should cause the
+    // manager to close the document, destroying the host.
+    ExtensionHostTestHelper host_waiter(profile());
+    host_waiter.RestrictToHost(offscreen_document);
+    ASSERT_TRUE(content::ExecuteScript(offscreen_document->host_contents(),
+                                       "window.close();"));
+    host_waiter.WaitForHostDestroyed();
+  }
+
+  EXPECT_EQ(nullptr,
+            offscreen_document_manager()->GetOffscreenDocumentForExtension(
+                *extension));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/extension_function_registration_test.cc b/chrome/browser/extensions/extension_function_registration_test.cc
index a9a51f10..3209c5c 100644
--- a/chrome/browser/extensions/extension_function_registration_test.cc
+++ b/chrome/browser/extensions/extension_function_registration_test.cc
@@ -31,6 +31,16 @@
 
   std::set<std::string> seen_names;
   std::set<functions::HistogramValue> seen_histograms;
+
+  // The following are methods that are undocumented and may or may not ship
+  // with a final API. We allow them to use the UNKNOWN histogram entry in the
+  // meantime.
+  // Each entry should have a bug number associated with it.
+  static const constexpr char* kAllowedUnknownHistogramEntries[] = {
+      // https://crbug.com/1339382.
+      "offscreen.hasDocument",
+  };
+
   for (const auto& key_value : factories) {
     const ExtensionFunctionRegistry::FactoryEntry& entry = key_value.second;
     SCOPED_TRACE(entry.function_name_);
@@ -40,11 +50,20 @@
     // for different functions.
     // EXPECT_TRUE(seen_factories.insert(entry.factory_).second);
 
-    // The chrome.test API uses an "unknown" histogram value, but should be the
-    // only API that does.
     if (entry.histogram_value_ == functions::UNKNOWN) {
-      EXPECT_TRUE(base::StartsWith(entry.function_name_, "test.",
-                                   base::CompareCase::SENSITIVE));
+      // The chrome.test API uses UNKNOWN; it's only used in tests.
+      if (base::StartsWith(entry.function_name_, "test.",
+                           base::CompareCase::SENSITIVE)) {
+        continue;
+      }
+      // Some undocumented, unlaunched APIs may also use UNKNOWN if it's unclear
+      // (or unlikely) if they will ever launch.
+      if (base::Contains(kAllowedUnknownHistogramEntries,
+                         std::string(entry.function_name_))) {
+        continue;
+      }
+      ADD_FAILURE() << "Un-allowlisted API found using UNKNOWN histogram entry."
+                    << entry.function_name_;
     } else {
       EXPECT_TRUE(seen_histograms.insert(entry.histogram_value_).second);
     }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 7ad19b9..7b8c208 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2464,12 +2464,12 @@
   {
     "name": "enable-migrate-default-chrome-app-to-web-apps-gsuite",
     "owners": [ "alancutter", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 104
+    "expiry_milestone": 110
   },
   {
     "name": "enable-migrate-default-chrome-app-to-web-apps-non-gsuite",
     "owners": [ "alancutter", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 104
+    "expiry_milestone": 110
   },
   {
     "name": "enable-nacl",
@@ -2639,7 +2639,7 @@
   {
     "name": "enable-preinstalled-web-app-duplication-fixer",
     "owners": [ "alancutter" ],
-    "expiry_milestone": 104
+    "expiry_milestone": 110
   },
   {
     "name": "enable-prerender2",
@@ -4075,11 +4075,6 @@
     "expiry_milestone": 105
   },
   {
-    "name": "launcher-search-normalization",
-    "owners": ["wrong", "tby"],
-    "expiry_milestone": 101
-  },
-  {
     "name": "lazily-create-web-state-on-restoration",
     "owners": ["olivierrobin", "sdefresne"],
     "expiry_milestone": 105
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index ce6469e..625b61b 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4355,8 +4355,7 @@
 const char kArcFilePickerExperimentDescription[] =
     "Enables using ChromeOS file picker in ARC.";
 
-const char kArcGameModeName[] =
-    "Enable Game Mode for ARC";
+const char kArcGameModeName[] = "Enable Game Mode for ARC";
 const char kArcGameModeDescription[] =
     "ARC Fullscreen Games will request accomodation from ChromeOS for "
     "sustained performance.";
@@ -5315,7 +5314,8 @@
 
 const char kLauncherPlayStoreSearchName[] = "Launcher Play Store search";
 const char kLauncherPlayStoreSearchDescription[] =
-    "Enables Play Store search in the Launcher";
+    "Enables Play Store search in the Launcher. Only available in the "
+    "productivity launcher.";
 
 const char kLimitShelfItemsToActiveDeskName[] =
     "Limit Shelf items to active desk";
diff --git a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
index 948da7a7..a6b12ad 100644
--- a/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
+++ b/chrome/browser/lacros/web_app_provider_bridge_lacros.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/lacros/web_app_provider_bridge_lacros.h"
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/apps/app_service/webapk/webapk_utils.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/web_applications/commands/install_from_info_command.h"
@@ -41,28 +42,8 @@
   g_browser_process->profile_manager()->LoadProfileByPath(
       ProfileManager::GetPrimaryUserProfilePath(),
       /*incognito=*/false,
-      base::BindOnce(
-          [](mojom::ArcWebAppInstallInfoPtr arc_install_info,
-             WebAppInstalledInArcCallback callback, Profile* profile) {
-            DCHECK(profile);
-            auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
-            auto install_info = std::make_unique<WebAppInstallInfo>();
-            install_info->title = arc_install_info->title;
-            install_info->start_url = arc_install_info->start_url;
-            install_info->display_mode = blink::mojom::DisplayMode::kStandalone;
-            install_info->user_display_mode =
-                web_app::UserDisplayMode::kStandalone;
-            install_info->theme_color = arc_install_info->theme_color;
-            const SkBitmap& bitmap = *arc_install_info->icon.bitmap();
-            install_info->icon_bitmaps.any[bitmap.width()] = bitmap;
-
-            provider->command_manager().ScheduleCommand(
-                std::make_unique<web_app::InstallFromInfoCommand>(
-                    std::move(install_info), &provider->install_finalizer(),
-                    /*overwrite_existing_manifest_fields=*/false,
-                    webapps::WebappInstallSource::ARC, std::move(callback)));
-          },
-          std::move(arc_install_info), std::move(callback)));
+      base::BindOnce(&WebAppProviderBridgeLacros::WebAppInstalledInArcImpl,
+                     std::move(arc_install_info), std::move(callback)));
 }
 
 void WebAppProviderBridgeLacros::WebAppUninstalledInArc(
@@ -71,16 +52,61 @@
   g_browser_process->profile_manager()->LoadProfileByPath(
       ProfileManager::GetPrimaryUserProfilePath(),
       /*incognito=*/false,
-      base::BindOnce(
-          [](const std::string& app_id, WebAppUninstalledInArcCallback callback,
-             Profile* profile) {
-            DCHECK(profile);
-            auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
-            provider->install_finalizer().UninstallExternalWebApp(
-                app_id, web_app::WebAppManagement::kWebAppStore,
-                webapps::WebappUninstallSource::kArc, std::move(callback));
-          },
-          app_id, std::move(callback)));
+      base::BindOnce(&WebAppProviderBridgeLacros::WebAppUninstalledInArcImpl,
+                     app_id, std::move(callback)));
+}
+
+void WebAppProviderBridgeLacros::GetWebApkCreationParams(
+    const std::string& app_id,
+    GetWebApkCreationParamsCallback callback) {
+  g_browser_process->profile_manager()->LoadProfileByPath(
+      ProfileManager::GetPrimaryUserProfilePath(),
+      /*incognito=*/false,
+      base::BindOnce(&WebAppProviderBridgeLacros::GetWebApkCreationParamsImpl,
+                     app_id, std::move(callback)));
+}
+
+// static
+void WebAppProviderBridgeLacros::WebAppInstalledInArcImpl(
+    mojom::ArcWebAppInstallInfoPtr arc_install_info,
+    WebAppInstalledInArcCallback callback,
+    Profile* profile) {
+  DCHECK(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
+  auto install_info = std::make_unique<WebAppInstallInfo>();
+  install_info->title = arc_install_info->title;
+  install_info->start_url = arc_install_info->start_url;
+  install_info->display_mode = blink::mojom::DisplayMode::kStandalone;
+  install_info->user_display_mode = web_app::UserDisplayMode::kStandalone;
+  install_info->theme_color = arc_install_info->theme_color;
+  const SkBitmap& bitmap = *arc_install_info->icon.bitmap();
+  install_info->icon_bitmaps.any[bitmap.width()] = bitmap;
+
+  provider->command_manager().ScheduleCommand(
+      std::make_unique<web_app::InstallFromInfoCommand>(
+          std::move(install_info), &provider->install_finalizer(),
+          /*overwrite_existing_manifest_fields=*/false,
+          webapps::WebappInstallSource::ARC, std::move(callback)));
+}
+
+// static
+void WebAppProviderBridgeLacros::WebAppUninstalledInArcImpl(
+    const std::string& app_id,
+    WebAppUninstalledInArcCallback callback,
+    Profile* profile) {
+  DCHECK(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
+  provider->install_finalizer().UninstallExternalWebApp(
+      app_id, web_app::WebAppManagement::kWebAppStore,
+      webapps::WebappUninstallSource::kArc, std::move(callback));
+}
+
+// static
+void WebAppProviderBridgeLacros::GetWebApkCreationParamsImpl(
+    const std::string& app_id,
+    GetWebApkCreationParamsCallback callback,
+    Profile* profile) {
+  apps::GetWebApkCreationParams(profile, app_id, std::move(callback));
 }
 
 }  // namespace crosapi
diff --git a/chrome/browser/lacros/web_app_provider_bridge_lacros.h b/chrome/browser/lacros/web_app_provider_bridge_lacros.h
index bc54df0f5..d904482 100644
--- a/chrome/browser/lacros/web_app_provider_bridge_lacros.h
+++ b/chrome/browser/lacros/web_app_provider_bridge_lacros.h
@@ -8,6 +8,8 @@
 #include "chromeos/crosapi/mojom/web_app_service.mojom.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 
+class Profile;
+
 namespace crosapi {
 
 // Created in lacros-chrome. Allows ash-chrome to modify web app state in
@@ -25,8 +27,24 @@
                             WebAppInstalledInArcCallback callback) override;
   void WebAppUninstalledInArc(const std::string& app_id,
                               WebAppUninstalledInArcCallback callback) override;
+  void GetWebApkCreationParams(
+      const std::string& app_id,
+      GetWebApkCreationParamsCallback callback) override;
 
  private:
+  static void WebAppInstalledInArcImpl(
+      mojom::ArcWebAppInstallInfoPtr arc_install_info,
+      WebAppInstalledInArcCallback callback,
+      Profile* profile);
+  static void WebAppUninstalledInArcImpl(
+      const std::string& app_id,
+      WebAppUninstalledInArcCallback callback,
+      Profile* profile);
+  static void GetWebApkCreationParamsImpl(
+      const std::string& app_id,
+      GetWebApkCreationParamsCallback callback,
+      Profile* profile);
+
   mojo::Receiver<mojom::WebAppProviderBridge> receiver_{this};
 };
 
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc
index 0aa377c..3ff2b45 100644
--- a/chrome/browser/net/proxy_service_factory.cc
+++ b/chrome/browser/net/proxy_service_factory.cc
@@ -12,7 +12,6 @@
 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "net/proxy_resolution/configured_proxy_resolution_service.h"
 #include "net/proxy_resolution/proxy_config_service.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -55,9 +54,8 @@
   // configuration in case nothing is configured through prefs (Note: prefs
   // include command line and configuration policy).
 
-  base_service =
-      net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
-          base::ThreadTaskRunnerHandle::Get());
+  base_service = net::ProxyConfigService::CreateSystemProxyConfigService(
+      base::ThreadTaskRunnerHandle::Get());
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
   return tracker->CreateTrackingProxyConfigService(std::move(base_service));
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc
index 325b1b2..526e334 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.cc
+++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -77,10 +77,8 @@
 // UploadClient.
 class ReportingClient::Uploader : public UploaderInterface {
  public:
-  using UploadCallback =
-      base::OnceCallback<Status(bool,
-                                std::vector<EncryptedRecord>,
-                                absl::optional<ScopedReservation>)>;
+  using UploadCallback = base::OnceCallback<
+      Status(bool, std::vector<EncryptedRecord>, ScopedReservation)>;
 
   static std::unique_ptr<Uploader> Create(bool need_encryption_key,
                                           UploadCallback upload_callback) {
@@ -129,7 +127,7 @@
     bool completed_{false};
     const bool need_encryption_key_;
     std::vector<EncryptedRecord> encrypted_records_;
-    absl::optional<ScopedReservation> encrypted_records_reservation_;
+    ScopedReservation encrypted_records_reservation_;
 
     UploadCallback upload_callback_;
   };
@@ -157,9 +155,7 @@
     return;
   }
   encrypted_records_.emplace_back(std::move(data));
-  if (encrypted_records_reservation_.has_value()) {
-    encrypted_records_reservation_.value().HandOver(scoped_reservation);
-  }
+  encrypted_records_reservation_.HandOver(scoped_reservation);
   std::move(processed_cb).Run(true);
 }
 
@@ -198,8 +194,6 @@
       std::move(upload_callback_)
           .Run(need_encryption_key_, std::move(encrypted_records_),
                std::move(encrypted_records_reservation_));
-  // Make sure the reservation is invalidated.
-  encrypted_records_reservation_.reset();
   if (!upload_status.ok()) {
     LOG(ERROR) << "Unable to upload records: " << upload_status;
   }
@@ -356,12 +350,10 @@
                     [](EncryptedReportingUploadProvider* upload_provider,
                        bool need_encryption_key,
                        std::vector<EncryptedRecord> records,
-                       absl::optional<ScopedReservation> scoped_reservation) {
+                       ScopedReservation scoped_reservation) {
                       upload_provider->RequestUploadEncryptedRecords(
                           need_encryption_key, std::move(records),
                           std::move(scoped_reservation), base::DoNothing());
-                      // Make sure reservation is invalidated.
-                      scoped_reservation.reset();
                       return Status::StatusOK();
                     },
                     base::Unretained(instance->upload_provider_.get())));
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
index 72bddda9..b9dd0bb3 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.cc
@@ -72,7 +72,7 @@
 DmServerUploader::DmServerUploader(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     RecordHandler* handler,
     ReportSuccessfulUploadCallback report_success_upload_cb,
     EncryptionKeyAttachedCallback encryption_key_attached_cb,
@@ -111,6 +111,10 @@
   HandleRecords();
 }
 
+void DmServerUploader::OnCompletion() {
+  ScopedReservation release(std::move(scoped_reservation_));
+}
+
 void DmServerUploader::ProcessRecords() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   Status process_status;
@@ -209,7 +213,7 @@
 Status DmServerUploadService::EnqueueUpload(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     ReportSuccessfulUploadCallback report_upload_success_cb,
     EncryptionKeyAttachedCallback encryption_key_attached_cb) {
   Start<DmServerUploader>(need_encryption_key, std::move(records),
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
index ab62332c..65abcf0 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
@@ -22,10 +22,6 @@
 #include "components/reporting/util/task_runner_context.h"
 #include "net/base/backoff_entry.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chrome/browser/profiles/profile.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 namespace reporting {
 
 // DmServerUploadService uploads events to the DMServer. It does not manage
@@ -102,7 +98,7 @@
     DmServerUploader(
         bool need_encryption_key,
         std::vector<EncryptedRecord> records,
-        absl::optional<ScopedReservation> scoped_reservation,
+        ScopedReservation scoped_reservation,
         RecordHandler* handler,
         ReportSuccessfulUploadCallback report_success_upload_cb,
         EncryptionKeyAttachedCallback encryption_key_attached_cb,
@@ -116,6 +112,10 @@
     // handler size status from |handlers_|.
     void OnStart() override;
 
+    // OnComplete finalizes the uploader, releasing resources that are no longer
+    // used.
+    void OnCompletion() override;
+
     // ProcessRecords verifies that the records provided are parseable and sets
     // the |Record|s up for handling by the |RecordHandlers|s. On
     // completion, ProcessRecords |Schedule|s |HandleRecords|.
@@ -138,7 +138,7 @@
 
     const bool need_encryption_key_;
     std::vector<EncryptedRecord> encrypted_records_;
-    absl::optional<ScopedReservation> scoped_reservation_;
+    ScopedReservation scoped_reservation_;
     const ReportSuccessfulUploadCallback report_success_upload_cb_;
     const EncryptionKeyAttachedCallback encryption_key_attached_cb_;
     raw_ptr<RecordHandler> handler_;
@@ -165,7 +165,7 @@
   Status EnqueueUpload(
       bool need_encryption_key,
       std::vector<EncryptedRecord> records,
-      absl::optional<ScopedReservation> scoped_reservation,
+      ScopedReservation scoped_reservation,
       ReportSuccessfulUploadCallback report_upload_success_cb,
       EncryptionKeyAttachedCallback encryption_key_attached_cb);
 
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
index aaa762e5..6e17507 100644
--- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service_unittest.cc
@@ -18,14 +18,13 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
+#include "components/reporting/resources/memory_resource_impl.h"
+#include "components/reporting/resources/resource_interface.h"
 #include "components/reporting/util/status.h"
 #include "components/reporting/util/test_support_callbacks.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace reporting {
-namespace {
-
 using ::testing::_;
 using ::testing::Eq;
 using ::testing::Invoke;
@@ -35,6 +34,9 @@
 using ::testing::StrictMock;
 using ::testing::WithArgs;
 
+namespace reporting {
+namespace {
+
 // Ensures that profile cannot be null.
 TEST(DmServerUploadServiceTest, DeniesNullptrProfile) {
   content::BrowserTaskEnvironment task_envrionment;
@@ -45,6 +47,12 @@
               Property(&Status::error_code, Eq(error::INVALID_ARGUMENT)));
 }
 
+EncryptedRecord DummyRecord() {
+  EncryptedRecord record;
+  record.set_encrypted_wrapped_record("TEST_DATA");
+  return record;
+}
+
 class TestRecordHandler : public DmServerUploadService::RecordHandler {
  public:
   TestRecordHandler() : RecordHandler(/*client=*/nullptr) {}
@@ -71,7 +79,12 @@
  public:
   DmServerTest()
       : sequenced_task_runner_(base::ThreadPool::CreateSequencedTaskRunner({})),
-        handler_(std::make_unique<TestRecordHandler>()) {}
+        handler_(std::make_unique<TestRecordHandler>()),
+        memory_resource_(base::MakeRefCounted<MemoryResourceImpl>(
+            4u * 1024LLu * 1024LLu))  // 4 MiB
+  {}
+
+  virtual ~DmServerTest() { EXPECT_THAT(memory_resource_->GetUsed(), Eq(0uL)); }
 
  protected:
   content::BrowserTaskEnvironment task_envrionment_{
@@ -83,6 +96,8 @@
   std::vector<EncryptedRecord> records_;
 
   const base::TimeDelta kMaxDelay_ = base::Seconds(1);
+
+  scoped_refptr<ResourceInterface> memory_resource_;
 };
 
 class DmServerFailureTest : public DmServerTest,
@@ -103,8 +118,11 @@
 using TestEncryptionKeyAttached = MockFunction<void(SignedEncryptionInfo)>;
 
 TEST_P(DmServerUploaderTest, ProcessesRecord) {
-  // Add an empty record.
-  records_.emplace_back();
+  records_.emplace_back(DummyRecord());
+
+  ScopedReservation record_reservation(records_.back().ByteSizeLong(),
+                                       memory_resource_);
+  EXPECT_TRUE(record_reservation.reserved());
 
   const bool force_confirm_flag = force_confirm();
   EXPECT_CALL(*handler_, HandleRecords_(_, _, _, _))
@@ -135,10 +153,10 @@
 
   test::TestEvent<DmServerUploadService::CompletionResponse> callback_waiter;
   Start<DmServerUploadService::DmServerUploader>(
-      need_encryption_key(), std::move(records_),
-      /*scoped_reservation*/ absl::nullopt, handler_.get(),
-      std::move(successful_upload_cb), std::move(encryption_key_attached_cb),
-      callback_waiter.cb(), sequenced_task_runner_);
+      need_encryption_key(), std::move(records_), std::move(record_reservation),
+      handler_.get(), std::move(successful_upload_cb),
+      std::move(encryption_key_attached_cb), callback_waiter.cb(),
+      sequenced_task_runner_);
 
   const auto response = callback_waiter.result();
   EXPECT_OK(response);
@@ -148,6 +166,8 @@
   const int64_t kNumberOfRecords = 10;
   const int64_t kGenerationId = 1234;
 
+  ScopedReservation records_reservation(0uL, memory_resource_);
+  EXPECT_FALSE(records_reservation.reserved());
   for (int64_t i = 0; i < kNumberOfRecords; i++) {
     EncryptedRecord encrypted_record;
     encrypted_record.set_encrypted_wrapped_record(
@@ -157,8 +177,13 @@
     sequence_information->set_generation_id(kGenerationId);
     sequence_information->set_sequencing_id(i);
     sequence_information->set_priority(Priority::IMMEDIATE);
+    ScopedReservation record_reservation(encrypted_record.ByteSizeLong(),
+                                         memory_resource_);
+    EXPECT_TRUE(record_reservation.reserved());
+    records_reservation.HandOver(record_reservation);
     records_.push_back(std::move(encrypted_record));
   }
+  EXPECT_TRUE(records_reservation.reserved());
 
   const bool force_confirm_flag = force_confirm();
   EXPECT_CALL(*handler_, HandleRecords_(_, _, _, _))
@@ -190,7 +215,7 @@
   test::TestEvent<DmServerUploadService::CompletionResponse> callback_waiter;
   Start<DmServerUploadService::DmServerUploader>(
       need_encryption_key(), std::move(records_),
-      /*scoped_reservation*/ absl::nullopt, handler_.get(),
+      std::move(records_reservation), handler_.get(),
       std::move(successful_upload_cb), std::move(encryption_key_attached_cb),
       callback_waiter.cb(), sequenced_task_runner_);
 
@@ -199,8 +224,11 @@
 }
 
 TEST_P(DmServerUploaderTest, ReportsFailureToProcess) {
-  // Add an empty record.
-  records_.emplace_back();
+  records_.emplace_back(DummyRecord());
+
+  ScopedReservation record_reservation(records_.back().ByteSizeLong(),
+                                       memory_resource_);
+  EXPECT_TRUE(record_reservation.reserved());
 
   EXPECT_CALL(*handler_, HandleRecords_(_, _, _, _))
       .WillOnce(WithArgs<2>(
@@ -221,10 +249,10 @@
 
   test::TestEvent<DmServerUploadService::CompletionResponse> callback_waiter;
   Start<DmServerUploadService::DmServerUploader>(
-      need_encryption_key(), std::move(records_),
-      /*scoped_reservation*/ absl::nullopt, handler_.get(),
-      std::move(successful_upload_cb), std::move(encryption_key_attached_cb),
-      callback_waiter.cb(), sequenced_task_runner_);
+      need_encryption_key(), std::move(records_), std::move(record_reservation),
+      handler_.get(), std::move(successful_upload_cb),
+      std::move(encryption_key_attached_cb), callback_waiter.cb(),
+      sequenced_task_runner_);
 
   const auto response = callback_waiter.result();
   EXPECT_THAT(response.status(),
@@ -232,6 +260,9 @@
 }
 
 TEST_P(DmServerUploaderTest, ReprotWithZeroRecords) {
+  ScopedReservation no_records_reservation(0uL, memory_resource_);
+  EXPECT_FALSE(no_records_reservation.reserved());
+
   StrictMock<TestSuccessfulUpload> successful_upload;
   EXPECT_CALL(successful_upload, Call(_, _))
       .Times(need_encryption_key() ? 1 : 0);
@@ -268,7 +299,7 @@
   test::TestEvent<DmServerUploadService::CompletionResponse> callback_waiter;
   Start<DmServerUploadService::DmServerUploader>(
       need_encryption_key(), std::move(records_),
-      /*scoped_reservation*/ absl::nullopt, handler_.get(),
+      std::move(no_records_reservation), handler_.get(),
       std::move(successful_upload_cb), std::move(encryption_key_attached_cb),
       callback_waiter.cb(), sequenced_task_runner_);
 
@@ -283,8 +314,12 @@
 
 TEST_P(DmServerFailureTest, ReportsFailureToUpload) {
   const error::Code& error_code = GetParam();
-  // Add an empty record.
-  records_.emplace_back();
+
+  records_.emplace_back(DummyRecord());
+
+  ScopedReservation record_reservation(records_.back().ByteSizeLong(),
+                                       memory_resource_);
+  EXPECT_TRUE(record_reservation.reserved());
 
   EXPECT_CALL(*handler_, HandleRecords_(_, _, _, _))
       .WillOnce(WithArgs<2>(Invoke(
@@ -305,7 +340,7 @@
   test::TestEvent<DmServerUploadService::CompletionResponse> callback_waiter;
   Start<DmServerUploadService::DmServerUploader>(
       /*need_encryption_key*/ true, std::move(records_),
-      /*scoped_reservation*/ absl::nullopt, handler_.get(),
+      std::move(record_reservation), handler_.get(),
       std::move(successful_upload_cb), std::move(encryption_key_attached_cb),
       callback_waiter.cb(), sequenced_task_runner_);
 
diff --git a/chrome/browser/policy/messaging_layer/upload/fake_upload_client.cc b/chrome/browser/policy/messaging_layer/upload/fake_upload_client.cc
index 5f433f5..bc13b01 100644
--- a/chrome/browser/policy/messaging_layer/upload/fake_upload_client.cc
+++ b/chrome/browser/policy/messaging_layer/upload/fake_upload_client.cc
@@ -94,7 +94,7 @@
 Status FakeUploadClient::EnqueueUpload(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     ReportSuccessfulUploadCallback report_upload_success_cb,
     EncryptionKeyAttachedCallback encryption_key_attached_cb) {
   UploadEncryptedReportingRequestBuilder builder;
@@ -121,7 +121,7 @@
 }
 
 void FakeUploadClient::OnUploadComplete(
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     ReportSuccessfulUploadCallback report_upload_success_cb,
     EncryptionKeyAttachedCallback encryption_key_attached_cb,
     absl::optional<base::Value::Dict> response) {
diff --git a/chrome/browser/policy/messaging_layer/upload/fake_upload_client.h b/chrome/browser/policy/messaging_layer/upload/fake_upload_client.h
index 9878d6a..4313a4ae 100644
--- a/chrome/browser/policy/messaging_layer/upload/fake_upload_client.h
+++ b/chrome/browser/policy/messaging_layer/upload/fake_upload_client.h
@@ -23,7 +23,7 @@
   Status EnqueueUpload(
       bool need_encryption_key,
       std::vector<EncryptedRecord> records,
-      absl::optional<ScopedReservation> scoped_reservation,
+      ScopedReservation scoped_reservation,
       ReportSuccessfulUploadCallback report_upload_success_cb,
       EncryptionKeyAttachedCallback encryption_key_attached_cb) override;
 
@@ -31,7 +31,7 @@
   explicit FakeUploadClient(policy::CloudPolicyClient* cloud_policy_client);
 
   void OnUploadComplete(
-      absl::optional<ScopedReservation> scoped_reservation,
+      ScopedReservation scoped_reservation,
       ReportSuccessfulUploadCallback report_upload_success_cb,
       EncryptionKeyAttachedCallback encryption_key_attached_cb,
       absl::optional<base::Value::Dict> response);
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client.cc b/chrome/browser/policy/messaging_layer/upload/upload_client.cc
index ecfe067..05e8904 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_client.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_client.cc
@@ -42,7 +42,7 @@
 Status UploadClient::EnqueueUpload(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     ReportSuccessfulUploadCallback report_upload_success_cb,
     EncryptionKeyAttachedCallback encryption_key_attached_cb) {
   if (records.empty() && !need_encryption_key) {
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client.h b/chrome/browser/policy/messaging_layer/upload/upload_client.h
index 3a84fcd4d..07fc1bf 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_client.h
+++ b/chrome/browser/policy/messaging_layer/upload/upload_client.h
@@ -47,7 +47,7 @@
   virtual Status EnqueueUpload(
       bool need_encryption_key,
       std::vector<EncryptedRecord> record,
-      absl::optional<ScopedReservation> scoped_reservation,
+      ScopedReservation scoped_reservation,
       ReportSuccessfulUploadCallback report_upload_success_cb,
       EncryptionKeyAttachedCallback encryption_key_attached_cb);
 
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
index 59ed3720..1a6978d 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
@@ -23,6 +23,7 @@
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/reporting/proto/synced/record.pb.h"
 #include "components/reporting/proto/synced/record_constants.pb.h"
+#include "components/reporting/resources/memory_resource_impl.h"
 #include "components/reporting/util/test_support_callbacks.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -69,6 +70,9 @@
 
  protected:
   void SetUp() override {
+    memory_resource_ = base::MakeRefCounted<MemoryResourceImpl>(
+        4u * 1024LLu * 1024LLu);  // 4 MiB
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     // Set up fake primary profile.
     auto mock_user_manager =
@@ -92,6 +96,7 @@
     user_manager_.reset();
     profile_.reset();
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+    EXPECT_THAT(memory_resource_->GetUsed(), Eq(0uL));
   }
 
   bool need_encryption_key() const { return std::get<0>(GetParam()); }
@@ -103,6 +108,7 @@
   std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<user_manager::ScopedUserManager> user_manager_;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+  scoped_refptr<ResourceInterface> memory_resource_;
 };
 
 using TestEncryptionKeyAttached = MockFunction<void(SignedEncryptionInfo)>;
@@ -122,6 +128,7 @@
   record->set_data(json_data);
   record->set_destination(Destination::UPLOAD_EVENTS);
 
+  ScopedReservation total_reservation(0uL, memory_resource_);
   std::string serialized_record;
   wrapped_record.SerializeToString(&serialized_record);
   std::vector<EncryptedRecord> records;
@@ -133,6 +140,10 @@
     sequence_information->set_sequencing_id(static_cast<int64_t>(i));
     sequence_information->set_generation_id(kGenerationId);
     sequence_information->set_priority(Priority::IMMEDIATE);
+    ScopedReservation record_reservation(encrypted_record.ByteSizeLong(),
+                                         memory_resource_);
+    EXPECT_TRUE(record_reservation.reserved());
+    total_reservation.HandOver(record_reservation);
     records.push_back(encrypted_record);
   }
 
@@ -203,9 +214,8 @@
 
   auto upload_client = std::move(upload_client_result.ValueOrDie());
   auto enqueue_result = upload_client->EnqueueUpload(
-      need_encryption_key(), std::move(records),
-      /*scoped_reservation*/ absl::nullopt, std::move(upload_success_cb),
-      encryption_key_attached_cb);
+      need_encryption_key(), std::move(records), std::move(total_reservation),
+      std::move(upload_success_cb), encryption_key_attached_cb);
   EXPECT_TRUE(enqueue_result.ok());
 
   auto upload_success_result = upload_success.result();
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_provider.cc b/chrome/browser/policy/messaging_layer/upload/upload_provider.cc
index 5b8a0b5..2a7c5537 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_provider.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_provider.cc
@@ -45,7 +45,7 @@
   // Uploads encrypted records (can be invoked on any thread).
   void EnqueueUpload(bool need_encryption_key,
                      std::vector<EncryptedRecord> records,
-                     absl::optional<ScopedReservation> scoped_reservation,
+                     ScopedReservation scoped_reservation,
                      base::OnceCallback<void(Status)> enqueued_cb) const;
 
  private:
@@ -67,11 +67,10 @@
   // Uploads encrypted records on sequenced task runner (and thus capable of
   // detecting whether upload client is ready or not). If not ready,
   // it will wait and then upload.
-  void EnqueueUploadInternal(
-      bool need_encryption_key,
-      std::vector<EncryptedRecord> records,
-      absl::optional<ScopedReservation> scoped_reservation,
-      base::OnceCallback<void(Status)> enqueued_cb);
+  void EnqueueUploadInternal(bool need_encryption_key,
+                             std::vector<EncryptedRecord> records,
+                             ScopedReservation scoped_reservation,
+                             base::OnceCallback<void(Status)> enqueued_cb);
 
   // Sequence task runner and checker used during
   // |PostNewCloudPolicyClientRequest| processing.
@@ -221,12 +220,13 @@
   // Upload client is ready, upload all previously stored requests (if any).
   while (!stored_records_.empty() || stored_need_encryption_key_) {
     std::vector<EncryptedRecord> records;
-    absl::optional<ScopedReservation> scoped_reservation;
+    ScopedReservation scoped_reservation;
     if (!stored_records_.empty()) {
       records = std::move(stored_records_.begin()->second);
       auto it = stored_reservations_.find(stored_records_.begin()->first);
       if (it != stored_reservations_.end()) {
-        scoped_reservation.emplace(std::move(*it->second));
+        scoped_reservation.HandOver(*it->second);
+        DCHECK(!it->second->reserved());
         stored_reservations_.erase(it);
       }
       stored_records_.erase(stored_records_.begin());
@@ -245,7 +245,7 @@
 void EncryptedReportingUploadProvider::UploadHelper::EnqueueUpload(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     base::OnceCallback<void(Status)> enqueued_cb) const {
   sequenced_task_runner_->PostTask(
       FROM_HERE,
@@ -258,7 +258,7 @@
 void EncryptedReportingUploadProvider::UploadHelper::EnqueueUploadInternal(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     base::OnceCallback<void(Status)> enqueued_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequenced_task_checker_);
   if (upload_client_ == nullptr) {
@@ -269,11 +269,9 @@
       generation_id = records.begin()->sequence_information().generation_id();
     }
     stored_records_.emplace(generation_id, std::move(records));
-    if (scoped_reservation.has_value()) {
-      stored_reservations_.emplace(generation_id,
-                                   std::make_unique<ScopedReservation>(
-                                       std::move(scoped_reservation.value())));
-    }
+    stored_reservations_.emplace(
+        generation_id,
+        std::make_unique<ScopedReservation>(std::move(scoped_reservation)));
     // Report success even though the upload has not been executed.
     // Actual success is reported through two permanent repeating callbacks.
     std::move(enqueued_cb).Run(Status::StatusOK());
@@ -308,7 +306,7 @@
 void EncryptedReportingUploadProvider::RequestUploadEncryptedRecords(
     bool need_encryption_key,
     std::vector<EncryptedRecord> records,
-    absl::optional<ScopedReservation> scoped_reservation,
+    ScopedReservation scoped_reservation,
     base::OnceCallback<void(Status)> result_cb) {
   DCHECK(helper_);
   helper_->EnqueueUpload(need_encryption_key, std::move(records),
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_provider.h b/chrome/browser/policy/messaging_layer/upload/upload_provider.h
index ae3c000..db1b0bf 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_provider.h
+++ b/chrome/browser/policy/messaging_layer/upload/upload_provider.h
@@ -54,7 +54,7 @@
   void RequestUploadEncryptedRecords(
       bool need_encryption_key,
       std::vector<EncryptedRecord> records,
-      absl::optional<ScopedReservation> scoped_reservation,
+      ScopedReservation scoped_reservation,
       base::OnceCallback<void(Status)> result_cb);
 
  private:
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
index a8a5ee3..00ba5f6 100644
--- a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
@@ -16,6 +16,8 @@
 #include "chrome/browser/policy/messaging_layer/util/test_response_payload.h"
 #include "components/policy/core/common/cloud/dm_token.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
+#include "components/reporting/resources/memory_resource_impl.h"
+#include "components/reporting/resources/resource_interface.h"
 #include "components/reporting/util/test_support_callbacks.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -87,6 +89,8 @@
 
  protected:
   void SetUp() override {
+    memory_resource_ = base::MakeRefCounted<MemoryResourceImpl>(
+        4u * 1024LLu * 1024LLu);  // 4 MiB
     cloud_policy_client_.SetDMToken(
         policy::DMToken::CreateValidTokenForTesting("FAKE_DM_TOKEN").value());
     service_provider_ = std::make_unique<TestEncryptedReportingUploadProvider>(
@@ -106,10 +110,14 @@
     sequence_information->set_priority(reporting::Priority::SLOW_BATCH);
   }
 
+  void TearDown() override {
+    EXPECT_THAT(memory_resource_->GetUsed(), Eq(0uL));
+  }
+
   Status CallRequestUploadEncryptedRecord(
       bool need_encryption_key,
       std::vector<EncryptedRecord> records,
-      absl::optional<ScopedReservation> scoped_reservation) {
+      ScopedReservation scoped_reservation) {
     test::TestEvent<Status> result;
     service_provider_->RequestUploadEncryptedRecords(
         need_encryption_key, std::move(records), std::move(scoped_reservation),
@@ -123,6 +131,8 @@
   policy::MockCloudPolicyClient cloud_policy_client_;
   reporting::EncryptedRecord record_;
 
+  scoped_refptr<ResourceInterface> memory_resource_;
+
   std::unique_ptr<TestEncryptedReportingUploadProvider> service_provider_;
 };
 
@@ -138,9 +148,12 @@
 
   std::vector<EncryptedRecord> records;
   records.emplace_back(record_);
+  ScopedReservation record_reservation(records.back().ByteSizeLong(),
+                                       memory_resource_);
+  EXPECT_TRUE(record_reservation.reserved());
   const auto status = CallRequestUploadEncryptedRecord(
       /*need_encryption_key=*/false, std::move(records),
-      /*scoped_reservation=*/absl::nullopt);
+      std::move(record_reservation));
   EXPECT_OK(status) << status;
   auto uploaded_result = uploaded_event.result();
   EXPECT_THAT(std::get<0>(uploaded_result),
diff --git a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h
index a718cec..e290c91 100644
--- a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h
+++ b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.h
@@ -18,8 +18,7 @@
 
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
-// Any updates to this class need to be propagated to SearchPrefetchFinalStatus
-// in enums.xml.
+// Any updates to this class need to be propagated to enums.xml.
 enum class SearchPrefetchStatus {
   // The request has not started yet. This status should ideally never be
   // recorded as Start() should be called on the same stack as creating the
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 4c04f24..706b463 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -163,10 +163,11 @@
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/constants/ash_features.h"
 #include "chrome/browser/ash/account_manager/account_apps_availability_factory.h"
 #include "chrome/browser/ash/browser_context_keyed_service_factories.h"
 #include "chrome/browser/ash/login/security_token_session_controller_factory.h"
-#include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
+#include "chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider_factory.h"
 #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 #else
@@ -556,8 +557,10 @@
   SupervisedUserServiceFactory::GetInstance();
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (ash::SystemExtensionsProvider::IsEnabled())
+  if (base::FeatureList::IsEnabled(ash::features::kSystemExtensions)) {
     ash::SystemExtensionsProviderFactory::GetInstance();
+    ash::CrosWindowManagementContextFactory::GetInstance();
+  }
 #endif
   TabRestoreServiceFactory::GetInstance();
   safe_browsing::TailoredSecurityServiceFactory::GetInstance();
diff --git a/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html b/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html
index 368544f1..b507663 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html
@@ -22,14 +22,6 @@
         transition: color 250ms linear, background-color 250ms linear;
       }
 
-      cr-card-radio-button {
-        transition: background-color 0ms;
-      }
-
-      cr-card-radio-button:hover {
-        transition: background-color 0ms;
-      }
-
       .card-label {
         color: var(--cros-text-color-primary);
         font-size: 16px;
diff --git a/chrome/browser/resources/tab_strip/tab_strip.html b/chrome/browser/resources/tab_strip/tab_strip.html
index dbd97e9..91c605c 100644
--- a/chrome/browser/resources/tab_strip/tab_strip.html
+++ b/chrome/browser/resources/tab_strip/tab_strip.html
@@ -3,7 +3,7 @@
   <head>
     <meta charset="utf-8">
     <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
-    <link rel="stylesheet" href="chrome://theme/colors.css">
+    <link rel="stylesheet" href="chrome://theme/colors.css?sets=ui,chrome">
     <title>$i18n{tabListTitle}</title>
     <style>
       html {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 472f2659..6f3722f 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3156,6 +3156,7 @@
       "//chromeos/ash/services/assistant:lib",
       "//chromeos/ash/services/assistant/public/cpp",
       "//chromeos/ash/services/assistant/public/mojom",
+      "//chromeos/ash/services/assistant/public/proto",
       "//chromeos/ash/services/auth_factor_config",
       "//chromeos/components/onc",
       "//chromeos/components/quick_answers",
@@ -3177,7 +3178,6 @@
       "//chromeos/login/login_state",
       "//chromeos/network",
       "//chromeos/printing",
-      "//chromeos/services/assistant/public/proto",
       "//chromeos/services/assistant/public/shared",
       "//chromeos/services/bluetooth_config",
       "//chromeos/services/bluetooth_config:in_process_bluetooth_config",
@@ -3307,6 +3307,7 @@
       "//chromeos/strings",
       "//components/account_manager_core:account_manager_core",
       "//ui/chromeos/styles:cros_styles_views",
+      "//ui/chromeos/styles:cros_tokens_color_mappings",
     ]
   }
 
@@ -5419,7 +5420,6 @@
       "web_applications/share_target_utils.h",
       "web_applications/sub_apps_service_impl.cc",
       "web_applications/sub_apps_service_impl.h",
-      "web_applications/system_web_app_delegate_ui_impl.cc",
       "web_applications/web_app_browser_controller.cc",
       "web_applications/web_app_browser_controller.h",
       "web_applications/web_app_dialog_manager.cc",
diff --git a/chrome/browser/ui/ash/assistant/assistant_setup.cc b/chrome/browser/ui/ash/assistant/assistant_setup.cc
index a54c009..12e17bb 100644
--- a/chrome/browser/ui/ash/assistant/assistant_setup.cc
+++ b/chrome/browser/ui/ash/assistant/assistant_setup.cc
@@ -20,7 +20,7 @@
 #include "chromeos/ash/components/assistant/buildflags.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_service.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "components/prefs/pref_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
diff --git a/chrome/browser/ui/ash/system_web_apps/BUILD.gn b/chrome/browser/ui/ash/system_web_apps/BUILD.gn
index 87c45c6..b37521e7 100644
--- a/chrome/browser/ui/ash/system_web_apps/BUILD.gn
+++ b/chrome/browser/ui/ash/system_web_apps/BUILD.gn
@@ -10,6 +10,7 @@
 
 source_set("system_web_apps") {
   sources = [
+    "system_web_app_delegate_ui_impl.cc",
     "system_web_app_ui_utils.cc",
     "system_web_app_ui_utils.h",
   ]
diff --git a/chrome/browser/ui/web_applications/system_web_app_delegate_ui_impl.cc b/chrome/browser/ui/ash/system_web_apps/system_web_app_delegate_ui_impl.cc
similarity index 100%
rename from chrome/browser/ui/web_applications/system_web_app_delegate_ui_impl.cc
rename to chrome/browser/ui/ash/system_web_apps/system_web_app_delegate_ui_impl.cc
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index e0a8f06c..4251802 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -59,7 +59,8 @@
                                                  const std::string& file_name,
                                                  ash::WallpaperLayout layout,
                                                  const gfx::ImageSkia& image,
-                                                 bool preview_mode) {
+                                                 bool preview_mode,
+                                                 const std::string& file_path) {
   ++set_custom_wallpaper_count_;
 }
 
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index aef8408..25f7ad8 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -80,7 +80,8 @@
                           const std::string& file_name,
                           ash::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode) override;
+                          bool preview_mode,
+                          const std::string& file_path = "") override;
   void SetOnlineWallpaper(const ash::OnlineWallpaperParams& params,
                           SetWallpaperCallback callback) override;
   void SetOnlineWallpaperIfExists(const ash::OnlineWallpaperParams& params,
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
index a5c6012..059ab6b 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -313,11 +313,12 @@
     const std::string& file_name,
     ash::WallpaperLayout layout,
     const gfx::ImageSkia& image,
-    bool preview_mode) {
+    bool preview_mode,
+    const std::string& file_path) {
   if (!IsKnownUser(account_id))
     return;
   wallpaper_controller_->SetCustomWallpaper(account_id, file_name, layout,
-                                            image, preview_mode);
+                                            image, preview_mode, file_path);
 }
 
 void WallpaperControllerClientImpl::SetOnlineWallpaper(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
index 181b544..d699c61 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -108,7 +108,8 @@
                           const std::string& file_name,
                           ash::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
-                          bool preview_mode);
+                          bool preview_mode,
+                          const std::string& file_path = "");
   void SetOnlineWallpaper(
       const ash::OnlineWallpaperParams& params,
       ash::WallpaperController::SetWallpaperCallback callback);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index e0ef144..06baad6 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -111,6 +111,10 @@
 #include "chrome/browser/browser_process.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/ui/base/tablet_state.h"
+#endif
+
 namespace {
 
 using ::metrics::OmniboxEventProto;
@@ -455,7 +459,15 @@
 }
 
 gfx::Size OmniboxViewViews::GetMinimumSize() const {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // TODO(crbug.com/1338087): The minimum size of Lacros toolbar is set too wide
+  // to use split view in tablet mode. Temporally making the minimum size of
+  // omnibox smaller for Lacros to align the behavior with Ash.
+  const int kMinCharacters =
+      chromeos::TabletState::Get()->InTabletMode() ? 8 : 20;
+#else
   const int kMinCharacters = 20;
+#endif
   return gfx::Size(
       GetFontList().GetExpectedTextWidth(kMinCharacters) + GetInsets().width(),
       GetPreferredSize().height());
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
index 34e29e5..221c1cc09 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
@@ -18,7 +18,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
-#include "chromeos/services/assistant/public/proto/activity_control_settings_common.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/activity_control_settings_common.pb.h"
 #include "components/consent_auditor/consent_auditor.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/consent_level.h"
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
index 0ee6358e..9f567a3 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "components/sync/protocol/user_consent_types.pb.h"
 
 class PrefService;
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
index 101acfe8..63fb9ffa 100644
--- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -24,9 +24,9 @@
 #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
 #include "chromeos/ash/services/assistant/public/cpp/assistant_service.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
+#include "chromeos/ash/services/assistant/public/proto/get_settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/dbus/power/power_manager_client.h"
-#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
 #include "components/login/localized_values_builder.h"
 #include "components/prefs/pref_service.h"
 #include "components/session_manager/core/session_manager.h"
diff --git a/chrome/browser/ui/webui/theme_source.cc b/chrome/browser/ui/webui/theme_source.cc
index f93be69..c9ff57de 100644
--- a/chrome/browser/ui/webui/theme_source.cc
+++ b/chrome/browser/ui/webui/theme_source.cc
@@ -4,13 +4,17 @@
 
 #include "chrome/browser/ui/webui/theme_source.h"
 
+#include <algorithm>
+
 #include "base/bind.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "build/branding_buildflags.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/resources_util.h"
 #include "chrome/browser/search/instant_service.h"
@@ -31,6 +35,7 @@
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
+#include "net/base/url_util.h"
 #include "services/network/public/mojom/content_security_policy.mojom.h"
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -42,6 +47,10 @@
 #include "ui/gfx/image/image_skia_rep.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace {
 
 GURL GetThemeUrl(const std::string& path) {
@@ -108,33 +117,7 @@
   // colors_css_updater.js.
   constexpr char kColorsCssPath[] = "colors.css";
   if (parsed_path == kColorsCssPath) {
-    const ui::ColorProvider& color_provider =
-        wc_getter.Run()->GetColorProvider();
-
-    auto generate_color_mapping = [](ui::ColorId start, ui::ColorId end,
-                                     std::string (*color_id_name)(ui::ColorId),
-                                     const ui::ColorProvider& color_provider) {
-      std::string css_string;
-      for (ui::ColorId id = start; id < end; ++id) {
-        const SkColor color = color_provider.GetColor(id);
-        std::string css_id_to_color_mapping = base::StringPrintf(
-            "%s:%s;",
-            ui::ConvertColorProviderColorIdToCSSColorId(color_id_name(id))
-                .c_str(),
-            ui::ConvertSkColorToCSSColor(color).c_str());
-        base::StrAppend(&css_string, {css_id_to_color_mapping});
-      }
-      return css_string;
-    };
-
-    std::string css_string = base::StrCat(
-        {"html {",
-         generate_color_mapping(ui::kUiColorsStart, ui::kUiColorsEnd,
-                                &ui::ColorIdName, color_provider),
-         generate_color_mapping(kChromeColorsStart, kChromeColorsEnd,
-                                &ChromeColorIdName, color_provider),
-         "}"});
-    std::move(callback).Run(base::RefCountedString::TakeString(&css_string));
+    SendColorsCss(url, wc_getter, std::move(callback));
     return;
   }
 
@@ -257,6 +240,94 @@
   std::move(callback).Run(data.get());
 }
 
+void ThemeSource::SendColorsCss(
+    const GURL& url,
+    const content::WebContents::Getter& wc_getter,
+    content::URLDataSource::GotDataCallback callback) {
+  const ui::ColorProvider& color_provider = wc_getter.Run()->GetColorProvider();
+
+  std::string sets_param;
+  std::vector<base::StringPiece> color_id_sets;
+  if (!net::GetValueForKeyInQuery(url, "sets", &sets_param)) {
+    LOG(ERROR)
+        << "colors.css requires a 'sets' query parameter to specify the color "
+           "id sets returned e.g chrome://theme/colors.css?sets=ui,chrome";
+    std::move(callback).Run(nullptr);
+    return;
+  }
+  color_id_sets = base::SplitStringPiece(sets_param, ",", base::TRIM_WHITESPACE,
+                                         base::SPLIT_WANT_ALL);
+
+  using ColorIdCSSCallback = base::RepeatingCallback<std::string(ui::ColorId)>;
+  auto generate_color_mapping = [&color_id_sets, &color_provider](
+                                    std::string set_name, ui::ColorId start,
+                                    ui::ColorId end,
+                                    ColorIdCSSCallback color_css_name) {
+    // Only return these mappings if specified in the query parameter.
+    auto it = std::find(color_id_sets.begin(), color_id_sets.end(), set_name);
+    if (it == color_id_sets.end()) {
+      return std::string();
+    }
+    color_id_sets.erase(it);
+    std::string css_string;
+    for (ui::ColorId id = start; id < end; ++id) {
+      const SkColor color = color_provider.GetColor(id);
+      std::string css_id_to_color_mapping =
+          base::StringPrintf("%s:%s;", color_css_name.Run(id).c_str(),
+                             ui::ConvertSkColorToCSSColor(color).c_str());
+      base::StrAppend(&css_string, {css_id_to_color_mapping});
+    }
+    return css_string;
+  };
+
+  // Convenience lambda for wrapping
+  // |ConvertColorProviderColorIdToCSSColorId|.
+  auto generate_color_provider_mapping = [&generate_color_mapping](
+                                             std::string set_name,
+                                             ui::ColorId start, ui::ColorId end,
+                                             std::string (*color_id_name)(
+                                                 ui::ColorId)) {
+    auto color_id_to_css_name = base::BindRepeating(
+        [](std::string (*color_id_name)(ui::ColorId), ui::ColorId id) {
+          return ui::ConvertColorProviderColorIdToCSSColorId(color_id_name(id));
+        },
+        color_id_name);
+    return generate_color_mapping(set_name, start, end, color_id_to_css_name);
+  };
+
+  std::string css_string = base::StrCat({
+    // This selector requires more specificity than other existing CSS
+    // selectors that define variables. We increase the specifity by adding
+    // a pseudoselector.
+    "html:not(#z) {",
+        generate_color_provider_mapping("ui", ui::kUiColorsStart,
+                                        ui::kUiColorsEnd, ui::ColorIdName),
+        generate_color_provider_mapping("chrome", kChromeColorsStart,
+                                        kChromeColorsEnd, &ChromeColorIdName),
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+        generate_color_mapping("ref", cros_tokens::kCrosRefColorsStart,
+                               cros_tokens::kCrosRefColorsEnd,
+                               base::BindRepeating(cros_tokens::ColorIdName)),
+        generate_color_mapping("sys", cros_tokens::kCrosSysColorsStart,
+                               cros_tokens::kCrosSysColorsEnd,
+                               base::BindRepeating(cros_tokens::ColorIdName)),
+        generate_color_mapping("legacy",
+                               cros_tokens::kLegacySemanticColorsStart,
+                               cros_tokens::kLegacySemanticColorsEnd,
+                               base::BindRepeating(cros_tokens::ColorIdName)),
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+        "}"
+  });
+  if (!color_id_sets.empty()) {
+    LOG(ERROR)
+        << "Unrecognized color set(s) specified for chrome://theme/colors.css: "
+        << base::JoinString(color_id_sets, ",");
+    std::move(callback).Run(nullptr);
+    return;
+  }
+  std::move(callback).Run(base::RefCountedString::TakeString(&css_string));
+}
+
 std::string ThemeSource::GetAccessControlAllowOriginForOrigin(
     const std::string& origin) {
   std::string allowed_origin_prefix = content::kChromeUIScheme;
diff --git a/chrome/browser/ui/webui/theme_source.h b/chrome/browser/ui/webui/theme_source.h
index b58abc6d..f434744 100644
--- a/chrome/browser/ui/webui/theme_source.h
+++ b/chrome/browser/ui/webui/theme_source.h
@@ -53,6 +53,13 @@
                       int resource_id,
                       float scale);
 
+  // Generates and sends a CSS stylesheet with colors from the |ColorProvider|.
+  // A 'sets' query parameter must be specified to indicate which colors should
+  // be in the stylesheet. e.g chrome://theme/colors.css?sets=ui,chrome
+  void SendColorsCss(const GURL& url,
+                     const content::WebContents::Getter& wc_getter,
+                     content::URLDataSource::GotDataCallback callback);
+
   // The profile this object was initialized with.
   raw_ptr<Profile> profile_;
 
diff --git a/chrome/browser/ui/webui/theme_source_unittest.cc b/chrome/browser/ui/webui/theme_source_unittest.cc
index 92795101..19079766 100644
--- a/chrome/browser/ui/webui/theme_source_unittest.cc
+++ b/chrome/browser/ui/webui/theme_source_unittest.cc
@@ -119,7 +119,7 @@
   // functions.
   size_t empty_size = 0;
 
-  StartDataRequest("colors.css");
+  StartDataRequest("colors.css?sets=ui");
   base::RunLoop().RunUntilIdle();
   EXPECT_NE(result_data_size_, empty_size);
 }
diff --git a/chrome/browser/web_applications/adjustments/link_capturing_pref_migration_browsertest.cc b/chrome/browser/web_applications/adjustments/link_capturing_pref_migration_browsertest.cc
index 654ca28b..4792997 100644
--- a/chrome/browser/web_applications/adjustments/link_capturing_pref_migration_browsertest.cc
+++ b/chrome/browser/web_applications/adjustments/link_capturing_pref_migration_browsertest.cc
@@ -23,8 +23,7 @@
   // InProcessBrowserTest:
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
-    web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(browser()->profile()));
+    test::WaitUntilReady(WebAppProvider::GetForTest(browser()->profile()));
   }
 
  protected:
diff --git a/chrome/browser/web_applications/adjustments/preinstalled_web_app_duplication_fixer_browsertest.cc b/chrome/browser/web_applications/adjustments/preinstalled_web_app_duplication_fixer_browsertest.cc
index f90ff2f..b62cd41e 100644
--- a/chrome/browser/web_applications/adjustments/preinstalled_web_app_duplication_fixer_browsertest.cc
+++ b/chrome/browser/web_applications/adjustments/preinstalled_web_app_duplication_fixer_browsertest.cc
@@ -75,7 +75,7 @@
 
     provider_ = WebAppProvider::GetForTest(browser()->profile());
     InProcessBrowserTest::SetUpOnMainThread();
-    web_app::test::WaitUntilReady(provider_);
+    test::WaitUntilReady(provider_);
 
     ExternalInstallOptions options(install_url(), UserDisplayMode::kStandalone,
                                    ExternalInstallSource::kExternalDefault);
diff --git a/chrome/browser/web_applications/adjustments/web_app_adjustments.cc b/chrome/browser/web_applications/adjustments/web_app_adjustments.cc
index 4cd26dd..51cde67 100644
--- a/chrome/browser/web_applications/adjustments/web_app_adjustments.cc
+++ b/chrome/browser/web_applications/adjustments/web_app_adjustments.cc
@@ -22,7 +22,7 @@
 WebAppAdjustments::WebAppAdjustments(Profile* profile) {
 #if BUILDFLAG(IS_CHROMEOS)
   link_capturing_pref_migration_ =
-      std::make_unique<web_app::LinkCapturingPrefMigration>(*profile);
+      std::make_unique<LinkCapturingPrefMigration>(*profile);
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
   if (base::FeatureList::IsEnabled(
diff --git a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
index fe815f8e..8d342b8 100644
--- a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
+++ b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
@@ -373,7 +373,7 @@
   // Writing to the external prefs to set policy to pin the app.
   web_app::test::AddInstallUrlData(
       browser()->profile()->GetPrefs(), &provider().sync_bridge(), app_id,
-      install_url, web_app::ExternalInstallSource::kExternalPolicy);
+      install_url, ExternalInstallSource::kExternalPolicy);
 
   provider().install_manager().NotifyWebAppInstalledWithOsHooks(app_id);
 
@@ -528,10 +528,9 @@
   launch_params->intent->files = std::move(files);
 
   // Skip past the permission dialog.
-  web_app::ScopedRegistryUpdate(
-      &web_app::WebAppProvider::GetForTest(profile())->sync_bridge())
+  ScopedRegistryUpdate(&WebAppProvider::GetForTest(profile())->sync_bridge())
       ->UpdateApp(app_id)
-      ->SetFileHandlerApprovalState(web_app::ApiApprovalState::kAllowed);
+      ->SetFileHandlerApprovalState(ApiApprovalState::kAllowed);
 
   lacros_web_apps_controller.Launch(std::move(launch_params),
                                     base::DoNothing());
@@ -600,8 +599,7 @@
 
   const GURL app_url =
       https_server()->GetURL("/web_app_shortcuts/shortcuts.html");
-  const web_app::AppId app_id =
-      web_app::InstallWebAppFromPage(browser(), app_url);
+  const AppId app_id = InstallWebAppFromPage(browser(), app_url);
   crosapi::mojom::AppController& lacros_web_apps_controller =
       *apps::AppServiceProxyFactory::GetForProfile(profile())
            ->LacrosWebAppsControllerForTesting();
@@ -633,8 +631,7 @@
                        ExecuteContextMenuCommand) {
   const GURL app_url =
       https_server()->GetURL("/web_app_shortcuts/shortcuts.html");
-  const web_app::AppId app_id =
-      web_app::InstallWebAppFromPage(browser(), app_url);
+  const AppId app_id = InstallWebAppFromPage(browser(), app_url);
   LacrosWebAppsController& lacros_web_apps_controller =
       *apps::AppServiceProxyFactory::GetForProfile(profile())
            ->LacrosWebAppsControllerForTesting();
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index 796178f..260bf99 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -181,7 +181,7 @@
 apps::mojom::InstallReason GetHighestPriorityInstallReason(
     const WebApp* web_app) {
   // TODO(crbug.com/1189949): Introduce kOem as a new WebAppManagement::Type
-  // value immediately below web_app::WebAppManagement::kSystem, so that this
+  // value immediately below WebAppManagement::kSystem, so that this
   // custom behavior isn't needed.
   if (web_app->chromeos_data().has_value()) {
     auto& chromeos_data = web_app->chromeos_data().value();
@@ -244,11 +244,11 @@
   }
 }
 
-bool IsNoteTakingWebApp(const web_app::WebApp& web_app) {
+bool IsNoteTakingWebApp(const WebApp& web_app) {
   return web_app.note_taking_new_note_url().is_valid();
 }
 
-bool IsLockScreenCapable(const web_app::WebApp& web_app) {
+bool IsLockScreenCapable(const WebApp& web_app) {
   if (!base::FeatureList::IsEnabled(features::kWebLockScreenApi))
     return false;
   return web_app.lock_screen_start_url().is_valid();
@@ -986,9 +986,9 @@
 
   if (permission->permission_type ==
       apps::mojom::PermissionType::kFileHandling) {
-    web_app::PersistFileHandlersUserChoice(profile_, app_id,
-                                           permission->value->get_bool_value(),
-                                           base::DoNothing());
+    PersistFileHandlersUserChoice(profile_, app_id,
+                                  permission->value->get_bool_value(),
+                                  base::DoNothing());
     return;
   }
 
@@ -1067,17 +1067,17 @@
 
 void WebAppPublisherHelper::SetWindowMode(const std::string& app_id,
                                           apps::mojom::WindowMode window_mode) {
-  auto user_display_mode = web_app::UserDisplayMode::kStandalone;
+  auto user_display_mode = UserDisplayMode::kStandalone;
   switch (window_mode) {
     case apps::mojom::WindowMode::kBrowser:
-      user_display_mode = web_app::UserDisplayMode::kBrowser;
+      user_display_mode = UserDisplayMode::kBrowser;
       break;
     case apps::mojom::WindowMode::kUnknown:
     case apps::mojom::WindowMode::kWindow:
-      user_display_mode = web_app::UserDisplayMode::kStandalone;
+      user_display_mode = UserDisplayMode::kStandalone;
       break;
     case apps::mojom::WindowMode::kTabbedWindow:
-      user_display_mode = web_app::UserDisplayMode::kTabbed;
+      user_display_mode = UserDisplayMode::kTabbed;
       break;
   }
   provider_->sync_bridge().SetAppUserDisplayMode(app_id, user_display_mode,
@@ -1093,20 +1093,18 @@
       ConvertOsLoginModeToWebAppConstants(run_on_os_login_mode));
 }
 
-web_app::RunOnOsLoginMode
-WebAppPublisherHelper::ConvertOsLoginModeToWebAppConstants(
+RunOnOsLoginMode WebAppPublisherHelper::ConvertOsLoginModeToWebAppConstants(
     apps::mojom::RunOnOsLoginMode login_mode) {
-  web_app::RunOnOsLoginMode web_app_constant_login_mode =
-      web_app::RunOnOsLoginMode::kMinValue;
+  RunOnOsLoginMode web_app_constant_login_mode = RunOnOsLoginMode::kMinValue;
   switch (login_mode) {
     case apps::mojom::RunOnOsLoginMode::kWindowed:
-      web_app_constant_login_mode = web_app::RunOnOsLoginMode::kWindowed;
+      web_app_constant_login_mode = RunOnOsLoginMode::kWindowed;
       break;
     case apps::mojom::RunOnOsLoginMode::kNotRun:
-      web_app_constant_login_mode = web_app::RunOnOsLoginMode::kNotRun;
+      web_app_constant_login_mode = RunOnOsLoginMode::kNotRun;
       break;
     case apps::mojom::RunOnOsLoginMode::kUnknown:
-      web_app_constant_login_mode = web_app::RunOnOsLoginMode::kNotRun;
+      web_app_constant_login_mode = RunOnOsLoginMode::kNotRun;
       break;
   }
   return web_app_constant_login_mode;
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
index 15499039..f52cf71 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
@@ -245,8 +245,8 @@
       blink::mojom::DisplayMode display_mode);
 
   // Converts RunOnOsLoginMode from apps::mojom::RunOnOsLoginMode to
-  // web_app::RunOnOsLoginMode.
-  web_app::RunOnOsLoginMode ConvertOsLoginModeToWebAppConstants(
+  // RunOnOsLoginMode.
+  RunOnOsLoginMode ConvertOsLoginModeToWebAppConstants(
       apps::mojom::RunOnOsLoginMode login_mode);
 
   void PublishWindowModeUpdate(const std::string& app_id,
diff --git a/chrome/browser/web_applications/commands/clear_browsing_data_command.cc b/chrome/browser/web_applications/commands/clear_browsing_data_command.cc
index ceff0520..99ba581 100644
--- a/chrome/browser/web_applications/commands/clear_browsing_data_command.cc
+++ b/chrome/browser/web_applications/commands/clear_browsing_data_command.cc
@@ -17,13 +17,13 @@
 
 void ClearWebAppBrowsingData(base::Time begin_time,
                              base::Time end_time,
-                             web_app::WebAppProvider* provider,
+                             WebAppProvider* provider,
                              base::OnceClosure done) {
   DCHECK_LE(begin_time, end_time);
 
   if (!provider->is_registry_ready()) {
     provider->on_registry_ready().Post(
-        FROM_HERE, base::BindOnce(&web_app::ClearWebAppBrowsingData, begin_time,
+        FROM_HERE, base::BindOnce(&ClearWebAppBrowsingData, begin_time,
                                   end_time, provider, std::move(done)));
     return;
   }
diff --git a/chrome/browser/web_applications/commands/clear_browsing_data_command.h b/chrome/browser/web_applications/commands/clear_browsing_data_command.h
index 2ff0b1a..5730a39 100644
--- a/chrome/browser/web_applications/commands/clear_browsing_data_command.h
+++ b/chrome/browser/web_applications/commands/clear_browsing_data_command.h
@@ -13,7 +13,7 @@
 // Clears the browsing data for web app, given the inclusive time range.
 void ClearWebAppBrowsingData(base::Time begin_time,
                              base::Time end_time,
-                             web_app::WebAppProvider* provider,
+                             WebAppProvider* provider,
                              base::OnceClosure done);
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/commands/clear_browsing_data_command_unittest.cc b/chrome/browser/web_applications/commands/clear_browsing_data_command_unittest.cc
index f5949a4..db06ad8 100644
--- a/chrome/browser/web_applications/commands/clear_browsing_data_command_unittest.cc
+++ b/chrome/browser/web_applications/commands/clear_browsing_data_command_unittest.cc
@@ -17,7 +17,7 @@
  protected:
   void SetUp() override {
     WebAppTest::SetUp();
-    web_app_provider_ = web_app::FakeWebAppProvider::Get(profile());
+    web_app_provider_ = FakeWebAppProvider::Get(profile());
     web_app_provider_->StartWithSubsystems();
   }
 
@@ -52,7 +52,7 @@
   auto app_id3 = web_app3->app_id();
 
   {
-    web_app::ScopedRegistryUpdate update(&provider()->sync_bridge());
+    ScopedRegistryUpdate update(&provider()->sync_bridge());
     update->CreateApp(std::move(web_app1));
     update->CreateApp(std::move(web_app2));
     update->CreateApp(std::move(web_app3));
@@ -67,7 +67,7 @@
             provider()->registrar().GetAppLastLaunchTime(app_id3));
 
   bool callback_invoked = false;
-  web_app::ClearWebAppBrowsingData(
+  ClearWebAppBrowsingData(
       base::Time(), base::Time::Now(), provider(),
       base::BindLambdaForTesting([&]() { callback_invoked = true; }));
 
@@ -98,7 +98,7 @@
   auto app_id3 = web_app3->app_id();
 
   {
-    web_app::ScopedRegistryUpdate update(&provider()->sync_bridge());
+    ScopedRegistryUpdate update(&provider()->sync_bridge());
     update->CreateApp(std::move(web_app1));
     update->CreateApp(std::move(web_app2));
     update->CreateApp(std::move(web_app3));
@@ -113,7 +113,7 @@
             provider()->registrar().GetAppLastLaunchTime(app_id3));
 
   bool callback_invoked = false;
-  web_app::ClearWebAppBrowsingData(
+  ClearWebAppBrowsingData(
       base::Time() + base::Seconds(5), base::Time() + base::Seconds(15),
       provider(),
       base::BindLambdaForTesting([&]() { callback_invoked = true; }));
@@ -130,7 +130,7 @@
 TEST_F(ClearBrowsingDataCommandTest,
        ClearLastLaunchTimeCalledBeforeWebAppProviderIsReady) {
   bool callback_invoked = false;
-  web_app::ClearWebAppBrowsingData(
+  ClearWebAppBrowsingData(
       base::Time(), base::Time::Now(), provider(),
       base::BindLambdaForTesting([&]() { callback_invoked = true; }));
 
@@ -159,7 +159,7 @@
   auto app_id3 = web_app3->app_id();
 
   {
-    web_app::ScopedRegistryUpdate update(&provider()->sync_bridge());
+    ScopedRegistryUpdate update(&provider()->sync_bridge());
     update->CreateApp(std::move(web_app1));
     update->CreateApp(std::move(web_app2));
     update->CreateApp(std::move(web_app3));
@@ -174,7 +174,7 @@
             provider()->registrar().GetAppLastBadgingTime(app_id3));
 
   bool callback_invoked = false;
-  web_app::ClearWebAppBrowsingData(
+  ClearWebAppBrowsingData(
       base::Time(), base::Time::Now(), provider(),
       base::BindLambdaForTesting([&]() { callback_invoked = true; }));
 
@@ -205,7 +205,7 @@
   auto app_id3 = web_app3->app_id();
 
   {
-    web_app::ScopedRegistryUpdate update(&provider()->sync_bridge());
+    ScopedRegistryUpdate update(&provider()->sync_bridge());
     update->CreateApp(std::move(web_app1));
     update->CreateApp(std::move(web_app2));
     update->CreateApp(std::move(web_app3));
@@ -220,7 +220,7 @@
             provider()->registrar().GetAppLastBadgingTime(app_id3));
 
   bool callback_invoked = false;
-  web_app::ClearWebAppBrowsingData(
+  ClearWebAppBrowsingData(
       base::Time() + base::Seconds(5), base::Time() + base::Seconds(15),
       provider(),
       base::BindLambdaForTesting([&]() { callback_invoked = true; }));
diff --git a/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc b/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc
index 0510513b..5e983b8 100644
--- a/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc
+++ b/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc
@@ -101,7 +101,7 @@
   info->title = u"Test name";
   info->start_url = GURL("http://test.com/path");
 
-  web_app::WebAppInstallParams install_params;
+  WebAppInstallParams install_params;
   install_params.bypass_os_hooks = false;
   install_params.add_to_applications_menu = true;
   install_params.add_to_desktop = true;
diff --git a/chrome/browser/web_applications/commands/install_web_app_with_params_command_browsertest.cc b/chrome/browser/web_applications/commands/install_web_app_with_params_command_browsertest.cc
index e9cf8af..f23c401 100644
--- a/chrome/browser/web_applications/commands/install_web_app_with_params_command_browsertest.cc
+++ b/chrome/browser/web_applications/commands/install_web_app_with_params_command_browsertest.cc
@@ -65,7 +65,7 @@
 
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      kWebAppUrl, web_app::UserDisplayMode::kStandalone,
+      kWebAppUrl, UserDisplayMode::kStandalone,
       ExternalInstallSource::kExternalDefault);
   auto install_params = ConvertExternalInstallOptionsToParams(install_options);
   auto install_source = ConvertExternalInstallSourceToInstallSource(
@@ -81,7 +81,7 @@
             EXPECT_EQ(code, webapps::InstallResultCode::kSuccessNewInstall);
             EXPECT_TRUE(provider().registrar().IsLocallyInstalled(app_id));
             EXPECT_EQ(
-                web_app::UserDisplayMode::kStandalone,
+                UserDisplayMode::kStandalone,
                 provider().registrar().GetAppUserDisplayMode(app_id).value());
             run_loop.Quit();
           }),
@@ -99,7 +99,7 @@
 
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      kWebAppUrl, web_app::UserDisplayMode::kBrowser,
+      kWebAppUrl, UserDisplayMode::kBrowser,
       ExternalInstallSource::kInternalDefault);
   auto install_params = ConvertExternalInstallOptionsToParams(install_options);
   auto install_source = ConvertExternalInstallSourceToInstallSource(
@@ -115,7 +115,7 @@
             EXPECT_EQ(code, webapps::InstallResultCode::kSuccessNewInstall);
             EXPECT_TRUE(provider().registrar().IsLocallyInstalled(app_id));
             EXPECT_EQ(
-                web_app::UserDisplayMode::kBrowser,
+                UserDisplayMode::kBrowser,
                 provider().registrar().GetAppUserDisplayMode(app_id).value());
             run_loop.Quit();
           }),
@@ -133,7 +133,7 @@
 
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      kWebAppUrl, web_app::UserDisplayMode::kBrowser,
+      kWebAppUrl, UserDisplayMode::kBrowser,
       ExternalInstallSource::kExternalPolicy);
   auto install_params = ConvertExternalInstallOptionsToParams(install_options);
   auto install_source = ConvertExternalInstallSourceToInstallSource(
@@ -166,7 +166,7 @@
 
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      kWebAppUrl, web_app::UserDisplayMode::kBrowser,
+      kWebAppUrl, UserDisplayMode::kBrowser,
       ExternalInstallSource::kExternalPolicy);
   auto install_params = ConvertExternalInstallOptionsToParams(install_options);
   auto install_source = ConvertExternalInstallSourceToInstallSource(
@@ -196,7 +196,7 @@
 
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      kWebAppUrl, web_app::UserDisplayMode::kBrowser,
+      kWebAppUrl, UserDisplayMode::kBrowser,
       ExternalInstallSource::kExternalPolicy);
   // This should force the install_params to have a valid manifest, otherwise
   // install will not happen.
diff --git a/chrome/browser/web_applications/commands/run_on_os_login_command.cc b/chrome/browser/web_applications/commands/run_on_os_login_command.cc
index 064f847..24d7c3b 100644
--- a/chrome/browser/web_applications/commands/run_on_os_login_command.cc
+++ b/chrome/browser/web_applications/commands/run_on_os_login_command.cc
@@ -55,13 +55,13 @@
   }
 
   if (effective_mode == RunOnOsLoginMode::kNotRun) {
-    web_app::OsHooksOptions os_hooks;
-    os_hooks[web_app::OsHookType::kRunOnOsLogin] = true;
+    OsHooksOptions os_hooks;
+    os_hooks[OsHookType::kRunOnOsLogin] = true;
     os_integration_manager->UninstallOsHooks(
         app_id, os_hooks, base::BindOnce(&MaybeCallTestingCallback));
   } else {
-    web_app::InstallOsHooksOptions install_options;
-    install_options.os_hooks[web_app::OsHookType::kRunOnOsLogin] = true;
+    InstallOsHooksOptions install_options;
+    install_options.os_hooks[OsHookType::kRunOnOsLogin] = true;
     os_integration_manager->InstallOsHooks(
         app_id, base::BindOnce(&MaybeCallTestingCallback), nullptr,
         std::move(install_options));
diff --git a/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc b/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
index 753fc16..e300c5d 100644
--- a/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
@@ -97,8 +97,8 @@
     return FakeInstallFinalizer::GetAppIdForUrl(url);
   }
 
-  void RegisterApp(std::unique_ptr<web_app::WebApp> web_app) {
-    web_app::AppId app_id = web_app->app_id();
+  void RegisterApp(std::unique_ptr<WebApp> web_app) {
+    AppId app_id = web_app->app_id();
     registrar_->registry().emplace(std::move(app_id), std::move(web_app));
   }
 
@@ -432,7 +432,7 @@
                       EXPECT_EQ(0u, finalizer()->num_reparent_tab_calls());
 
                       EXPECT_EQ(web_app_info().user_display_mode,
-                                web_app::UserDisplayMode::kBrowser);
+                                UserDisplayMode::kBrowser);
                       EXPECT_EQ(webapps::WebappInstallSource::INTERNAL_DEFAULT,
                                 finalize_options().install_surface);
 
@@ -445,7 +445,7 @@
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallFails) {
   const GURL kWebAppUrl("https://foo.example");
   auto task = GetInstallationTaskWithTestMocks(
-      {kWebAppUrl, web_app::UserDisplayMode::kStandalone,
+      {kWebAppUrl, UserDisplayMode::kStandalone,
        ExternalInstallSource::kInternalDefault},
       /*mock_empty_web_app_info=*/true);
   url_loader().SetPrepareForLoadResultLoaded();
@@ -476,7 +476,7 @@
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallForcedContainerWindow) {
   const GURL kWebAppUrl("https://foo.example");
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, web_app::UserDisplayMode::kStandalone,
+      ExternalInstallOptions(kWebAppUrl, UserDisplayMode::kStandalone,
                              ExternalInstallSource::kInternalDefault);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
   url_loader().SetPrepareForLoadResultLoaded();
@@ -491,7 +491,7 @@
                                 result.code);
                       EXPECT_TRUE(result.app_id.has_value());
                       EXPECT_EQ(web_app_info().user_display_mode,
-                                web_app::UserDisplayMode::kStandalone);
+                                UserDisplayMode::kStandalone);
                       run_loop.Quit();
                     }));
 
@@ -501,7 +501,7 @@
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallForcedContainerTab) {
   const GURL kWebAppUrl("https://foo.example");
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, web_app::UserDisplayMode::kBrowser,
+      ExternalInstallOptions(kWebAppUrl, UserDisplayMode::kBrowser,
                              ExternalInstallSource::kInternalDefault);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
   url_loader().SetPrepareForLoadResultLoaded();
@@ -516,7 +516,7 @@
                                 result.code);
                       EXPECT_TRUE(result.app_id.has_value());
                       EXPECT_EQ(web_app_info().user_display_mode,
-                                web_app::UserDisplayMode::kBrowser);
+                                UserDisplayMode::kBrowser);
                       run_loop.Quit();
                     }));
 
@@ -575,8 +575,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallPlaceholder) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   auto task = GetInstallationTaskWithTestMocks(std::move(options));
@@ -604,7 +603,7 @@
             EXPECT_EQ(base::UTF8ToUTF16(kWebAppUrl.spec()), web_app_info.title);
             EXPECT_EQ(kWebAppUrl, web_app_info.start_url);
             EXPECT_EQ(web_app_info.user_display_mode,
-                      web_app::UserDisplayMode::kStandalone);
+                      UserDisplayMode::kStandalone);
             EXPECT_TRUE(web_app_info.manifest_icons.empty());
             EXPECT_TRUE(web_app_info.icon_bitmaps.any.empty());
 
@@ -615,8 +614,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallPlaceholderTwice) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -668,8 +666,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, ReinstallPlaceholderSucceeds) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -727,8 +724,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, ReinstallPlaceholderFails) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -793,8 +789,7 @@
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallPlaceholderCustomName) {
   const GURL kWebAppUrl("https://foo.example");
   const std::string kCustomName("Custom äpp näme");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   options.override_name = kCustomName;
@@ -896,7 +891,7 @@
     base::RunLoop run_loop;
 
     ExternalInstallOptions install_options(
-        GURL(), web_app::UserDisplayMode::kStandalone,
+        GURL(), UserDisplayMode::kStandalone,
         ExternalInstallSource::kInternalDefault);
     ExternallyManagedAppInstallTask install_task(
         profile(), &url_loader(), registrar(), ui_manager(), finalizer(),
@@ -918,7 +913,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallFailedWebContentsDestroyed) {
   ExternalInstallOptions install_options(
-      GURL(), web_app::UserDisplayMode::kStandalone,
+      GURL(), UserDisplayMode::kStandalone,
       ExternalInstallSource::kInternalDefault);
   ExternallyManagedAppInstallTask install_task(
       profile(), &url_loader(), registrar(), ui_manager(), finalizer(),
@@ -937,8 +932,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallWithWebAppInfoSucceeds) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kSystemInstalled);
   options.only_use_app_info_factory = true;
   options.app_info_factory = base::BindLambdaForTesting([&kWebAppUrl]() {
@@ -974,7 +968,7 @@
             EXPECT_EQ(0u, finalizer()->num_reparent_tab_calls());
 
             EXPECT_EQ(web_app_info().user_display_mode,
-                      web_app::UserDisplayMode::kStandalone);
+                      UserDisplayMode::kStandalone);
             EXPECT_EQ(webapps::WebappInstallSource::SYSTEM_DEFAULT,
                       finalize_options().install_surface);
 
@@ -985,8 +979,7 @@
 
 TEST_P(ExternallyManagedAppInstallTaskTest, InstallWithWebAppInfoFails) {
   const GURL kWebAppUrl("https://foo.example");
-  ExternalInstallOptions options(kWebAppUrl,
-                                 web_app::UserDisplayMode::kStandalone,
+  ExternalInstallOptions options(kWebAppUrl, UserDisplayMode::kStandalone,
                                  ExternalInstallSource::kSystemInstalled);
   options.only_use_app_info_factory = true;
   options.app_info_factory = base::BindLambdaForTesting([&kWebAppUrl]() {
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
index 2fc3d9e..5e3e970 100644
--- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -477,7 +477,7 @@
               expected_default.run_on_os_login_policy);
   }
 
-  void RegisterApp(std::unique_ptr<web_app::WebApp> web_app) {
+  void RegisterApp(std::unique_ptr<WebApp> web_app) {
     controller().RegisterApp(std::move(web_app));
   }
 
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
index 6363bcc..15b49a6d 100644
--- a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
+++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
@@ -366,7 +366,7 @@
       }
     }
     // 2. If the value corresponding to the app_id in
-    // web_app::kWasExternalAppUninstalledByUser is true, then it was previously
+    // kWasExternalAppUninstalledByUser is true, then it was previously
     // a preinstalled app that was user uninstalled. In this case, we migrate
     // ALL install URLs for that corresponding app_id, because a preinstalled
     // app could have been installed as an app with a different source now.
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs_browsertest.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs_browsertest.cc
index dd7b7a2..b58dcf4 100644
--- a/chrome/browser/web_applications/externally_installed_web_app_prefs_browsertest.cc
+++ b/chrome/browser/web_applications/externally_installed_web_app_prefs_browsertest.cc
@@ -46,9 +46,8 @@
     auto web_app_install_info = std::make_unique<WebAppInstallInfo>();
     web_app_install_info->start_url = url;
     web_app_install_info->title = u"App Title";
-    web_app_install_info->display_mode = web_app::DisplayMode::kBrowser;
-    web_app_install_info->user_display_mode =
-        web_app::UserDisplayMode::kStandalone;
+    web_app_install_info->display_mode = DisplayMode::kBrowser;
+    web_app_install_info->user_display_mode = UserDisplayMode::kStandalone;
     web_app_install_info->install_url = url;
 
     AppId app_id;
@@ -155,9 +154,8 @@
   auto web_app_install_info = std::make_unique<WebAppInstallInfo>();
   web_app_install_info->start_url = url;
   web_app_install_info->title = u"App Title";
-  web_app_install_info->display_mode = web_app::DisplayMode::kBrowser;
-  web_app_install_info->user_display_mode =
-      web_app::UserDisplayMode::kStandalone;
+  web_app_install_info->display_mode = DisplayMode::kBrowser;
+  web_app_install_info->user_display_mode = UserDisplayMode::kStandalone;
   web_app_install_info->install_url = url;
 
   AppId app_id =
@@ -316,9 +314,8 @@
   auto web_app_install_info = std::make_unique<WebAppInstallInfo>();
   web_app_install_info->start_url = url;
   web_app_install_info->title = u"App Title";
-  web_app_install_info->display_mode = web_app::DisplayMode::kBrowser;
-  web_app_install_info->user_display_mode =
-      web_app::UserDisplayMode::kStandalone;
+  web_app_install_info->display_mode = DisplayMode::kBrowser;
+  web_app_install_info->user_display_mode = UserDisplayMode::kStandalone;
   web_app_install_info->install_url = url;
 
   AppId app_id =
@@ -541,9 +538,8 @@
     auto web_app_install_info = std::make_unique<WebAppInstallInfo>();
     web_app_install_info->start_url = url;
     web_app_install_info->title = u"App Title";
-    web_app_install_info->display_mode = web_app::DisplayMode::kBrowser;
-    web_app_install_info->user_display_mode =
-        web_app::UserDisplayMode::kStandalone;
+    web_app_install_info->display_mode = DisplayMode::kBrowser;
+    web_app_install_info->user_display_mode = UserDisplayMode::kStandalone;
     AppId app_id =
         test::InstallWebApp(profile(), std::move(web_app_install_info),
                             /*overwrite_existing_manifest_fields=*/true,
@@ -586,9 +582,8 @@
     auto web_app_install_info = std::make_unique<WebAppInstallInfo>();
     web_app_install_info->start_url = url;
     web_app_install_info->title = u"App Title";
-    web_app_install_info->display_mode = web_app::DisplayMode::kBrowser;
-    web_app_install_info->user_display_mode =
-        web_app::UserDisplayMode::kStandalone;
+    web_app_install_info->display_mode = DisplayMode::kBrowser;
+    web_app_install_info->user_display_mode = UserDisplayMode::kStandalone;
     web_app_install_info->install_url = url;
     app_id = test::InstallWebApp(profile(), std::move(web_app_install_info),
                                  /*overwrite_existing_manifest_fields=*/true,
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
index 791a05c..0d67e58 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
@@ -47,8 +47,7 @@
     InProcessBrowserTest::SetUpOnMainThread();
     // Allow different origins to be handled by the embedded_test_server.
     host_resolver()->AddRule("*", "127.0.0.1");
-    web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(profile()));
+    test::WaitUntilReady(WebAppProvider::GetForTest(profile()));
   }
 
   Profile* profile() { return browser()->profile(); }
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_unittest.cc b/chrome/browser/web_applications/externally_managed_app_manager_unittest.cc
index 18bc8d1..b5d2812 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_unittest.cc
@@ -150,7 +150,7 @@
     return *fake_registry_controller_;
   }
 
-  web_app::WebAppRegistrar& app_registrar() { return controller().registrar(); }
+  WebAppRegistrar& app_registrar() { return controller().registrar(); }
 
   ExternallyInstalledWebAppPrefs& externally_installed_app_prefs() {
     return *externally_installed_app_prefs_;
diff --git a/chrome/browser/web_applications/isolated_app_browsertest.cc b/chrome/browser/web_applications/isolated_app_browsertest.cc
index 70ea961b..9ccb6eb 100644
--- a/chrome/browser/web_applications/isolated_app_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_app_browsertest.cc
@@ -238,7 +238,7 @@
   // The app's frame should belong to an isolated PWA browser window.
   Browser* app_browser = GetBrowserFromFrame(app_frame);
   EXPECT_NE(app_browser, browser());
-  EXPECT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id));
+  EXPECT_TRUE(AppBrowserController::IsForWebApp(app_browser, app_id));
   EXPECT_EQ(content::RenderFrameHost::WebExposedIsolationLevel::
                 kMaybeIsolatedApplication,
             app_frame->GetWebExposedIsolationLevel());
@@ -265,7 +265,7 @@
   // The app's frame should belong to an isolated PWA browser window.
   Browser* app_browser = GetBrowserFromFrame(app_frame);
   EXPECT_NE(app_browser, browser());
-  EXPECT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id));
+  EXPECT_TRUE(AppBrowserController::IsForWebApp(app_browser, app_id));
   EXPECT_EQ(content::RenderFrameHost::WebExposedIsolationLevel::
                 kMaybeIsolatedApplication,
             app_frame->GetWebExposedIsolationLevel());
@@ -521,7 +521,7 @@
       NotificationHandler::Type::WEB_PERSISTENT);
   EXPECT_EQ(notifications.size(), 1UL);
 
-  web_app::BrowserWaiter browser_waiter(nullptr);
+  BrowserWaiter browser_waiter(nullptr);
   notification_tester_->SimulateClick(NotificationHandler::Type::WEB_PERSISTENT,
                                       notifications[0].id(), absl::nullopt,
                                       absl::nullopt);
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index 4c7c196..e9754df9 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -323,8 +323,7 @@
   void SetUpOnMainThread() override {
     // Cannot construct RunLoop in constructor due to threading restrictions.
     shortcut_run_loop_.emplace();
-    web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(browser()->profile()));
+    test::WaitUntilReady(WebAppProvider::GetForTest(browser()->profile()));
   }
 
   void OnShortcutInfoRetrieved(std::unique_ptr<ShortcutInfo> shortcut_info) {
@@ -348,7 +347,7 @@
     // The Mac code in generating these icons doesn't write a size 48 icon. See
     // chrome/browser/web_applications/web_app_icon_generator.h's
     // `kInstallIconSize`. Skip it.
-    if (size == web_app::icon_size::k48)
+    if (size == icon_size::k48)
       return false;
     return os == kMac || os == kNotWin || os == kAll;
 #else
diff --git a/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_linux_browsertest.cc b/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_linux_browsertest.cc
index 5ce3546..01e2e81b 100644
--- a/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_linux_browsertest.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_file_handler_registration_linux_browsertest.cc
@@ -61,8 +61,8 @@
   }
 
   void InstallApp(ExternalInstallOptions install_options) {
-    auto result = web_app::ExternallyManagedAppManagerInstall(
-        browser()->profile(), install_options);
+    auto result = ExternallyManagedAppManagerInstall(browser()->profile(),
+                                                     install_options);
     result_code_ = result.code;
   }
 
diff --git a/chrome/browser/web_applications/os_integration/web_app_handler_registration_utils_win.cc b/chrome/browser/web_applications/os_integration/web_app_handler_registration_utils_win.cc
index 11397bf..99a67173 100644
--- a/chrome/browser/web_applications/os_integration/web_app_handler_registration_utils_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_handler_registration_utils_win.cc
@@ -138,7 +138,7 @@
 // registries. Changes to how they are generated will be disruptive to
 // previously written values, and should therefore be avoided if possible.
 std::wstring GetProgId(const base::FilePath& profile_path,
-                       const web_app::AppId& app_id,
+                       const AppId& app_id,
                        const absl::optional<std::set<std::string>>&
                            file_extensions = absl::nullopt) {
   // On system-level Win7 installs of the browser we need a user-specific part
diff --git a/chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.cc b/chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.cc
index e8ebe5ce..abdf4ef 100644
--- a/chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.cc
@@ -84,7 +84,7 @@
   std::vector<ProtocolHandler> protocol_handlers;
 
   for (const WebApp& web_app : app_registrar_->GetApps()) {
-    web_app::AppId app_id = web_app.app_id();
+    AppId app_id = web_app.app_id();
 
     if (!app_registrar_->IsAllowedLaunchProtocol(app_id, protocol))
       continue;
@@ -108,7 +108,7 @@
   std::vector<ProtocolHandler> protocol_handlers;
 
   for (const WebApp& web_app : app_registrar_->GetApps()) {
-    web_app::AppId app_id = web_app.app_id();
+    AppId app_id = web_app.app_id();
 
     if (!app_registrar_->IsDisallowedLaunchProtocol(app_id, protocol))
       continue;
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_chromeos.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_chromeos.cc
index d2caf91..7e1a56d 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_chromeos.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_chromeos.cc
@@ -29,7 +29,7 @@
 void DeletePlatformShortcuts(const base::FilePath& web_app_path,
                              const ShortcutInfo& shortcut_info,
                              scoped_refptr<base::TaskRunner> result_runner,
-                             web_app::DeleteShortcutsCallback callback) {
+                             DeleteShortcutsCallback callback) {
   result_runner->PostTask(FROM_HERE, base::BindOnce(std::move(callback),
                                                     /*shortcut_deleted=*/true));
 }
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
index 6b4fc62..350370a 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
@@ -263,7 +263,7 @@
   // Because shims created in ~/Applications will not be cleaned up.
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kTestType) &&
-         !web_app::GetShortcutOverrideForTesting();
+         !GetShortcutOverrideForTesting();
 }
 
 bool AppShimRevealDisabledForTest() {
@@ -782,7 +782,7 @@
 }
 
 base::FilePath GetChromeAppsFolder() {
-  auto* override = web_app::GetShortcutOverrideForTesting();
+  auto* override = GetShortcutOverrideForTesting();
   if (override) {
     if (override->chrome_apps_folder.IsValid())
       return override->chrome_apps_folder.GetPath();
@@ -813,7 +813,7 @@
 
 void WebAppAutoLoginUtil::AddToLoginItems(const base::FilePath& app_bundle_path,
                                           bool hide_on_startup) {
-  auto* override = web_app::GetShortcutOverrideForTesting();
+  auto* override = GetShortcutOverrideForTesting();
   if (override) {
     override->startup_enabled[app_bundle_path] = true;
   } else {
@@ -823,7 +823,7 @@
 
 void WebAppAutoLoginUtil::RemoveFromLoginItems(
     const base::FilePath& app_bundle_path) {
-  auto* override = web_app::GetShortcutOverrideForTesting();
+  auto* override = GetShortcutOverrideForTesting();
   if (override) {
     override->startup_enabled[app_bundle_path] = false;
   } else {
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
index c4c45cd..4a6243b 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_win.cc
@@ -233,7 +233,7 @@
 }
 
 void DeleteShortcuts(std::vector<base::FilePath> all_shortcuts,
-                     web_app::DeleteShortcutsCallback result_callback) {
+                     DeleteShortcutsCallback result_callback) {
   bool result = true;
   for (const auto& shortcut : all_shortcuts) {
     if (!base::DeleteFile(shortcut))
@@ -408,7 +408,7 @@
     const base::FilePath& web_app_path,
     const base::FilePath& profile_path,
     const std::u16string& title,
-    web_app::DeleteShortcutsCallback result_callback) {
+    DeleteShortcutsCallback result_callback) {
   const std::vector<base::FilePath> all_shortcuts =
       FindMatchingShortcuts(web_app_path, profile_path, title);
 
@@ -669,7 +669,7 @@
 void FinishDeletingPlatformShortcuts(
     const base::FilePath& web_app_path,
     scoped_refptr<base::TaskRunner> result_runner,
-    web_app::DeleteShortcutsCallback result_callback,
+    DeleteShortcutsCallback result_callback,
     bool delete_result) {
   // If there are no more shortcuts in the Chrome Apps subdirectory, remove it.
   base::FilePath chrome_apps_dir;
@@ -722,7 +722,7 @@
   std::vector<base::FilePath> shortcut_paths;
   // if there is no ShortcutOverrirdeForTesting, set it to empty.
   ScopedShortcutOverrideForTesting* testing_shortcuts =
-      web_app::GetShortcutOverrideForTesting();
+      GetShortcutOverrideForTesting();
   // Locations to add to shortcut_paths.
   struct {
     bool use_this_location;
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
index 9759ff2..9268970 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcuts_menu_win.cc
@@ -39,8 +39,8 @@
 constexpr int kMaxJumpListItems = 10;
 
 // Testing hook for shell_integration_linux
-web_app::UpdateJumpListForTesting& GetUpdateJumpListForTesting() {
-  static base::NoDestructor<web_app::UpdateJumpListForTesting> instance;
+UpdateJumpListForTesting& GetUpdateJumpListForTesting() {
+  static base::NoDestructor<UpdateJumpListForTesting> instance;
   return *instance;
 }
 
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
index 5df72d3..9d61034 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -174,7 +174,7 @@
 void WebAppPolicyManager::OnDisableListPolicyChanged() {
 #if BUILDFLAG(IS_CHROMEOS)
   PopulateDisabledWebAppsIdsLists();
-  std::vector<web_app::AppId> app_ids = app_registrar_->GetAppIds();
+  std::vector<AppId> app_ids = app_registrar_->GetAppIds();
   for (const auto& id : app_ids) {
     const bool is_disabled = base::Contains(disabled_web_apps_, id);
     sync_bridge_->SetAppIsDisabled(id, is_disabled);
@@ -645,7 +645,7 @@
         disabled_system_apps_.insert(ash::SystemWebAppType::HELP);
         break;
       case policy::SystemFeature::kCanvas:
-        disabled_web_apps_.insert(web_app::kCanvasAppId);
+        disabled_web_apps_.insert(kCanvasAppId);
         break;
       case policy::SystemFeature::kCrosh:
         disabled_system_apps_.insert(ash::SystemWebAppType::CROSH);
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
index ae8cd5a..7b6e313 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager_browsertest.cc
@@ -239,7 +239,7 @@
 
   auto* provider = WebAppProvider::GetForTest(profile());
   provider->command_manager().ScheduleCommand(
-      std::make_unique<web_app::InstallFromInfoCommand>(
+      std::make_unique<InstallFromInfoCommand>(
           std::move(install_info), &provider->install_finalizer(),
           /*overwrite_existing_manifest_fields=*/true,
           webapps::WebappInstallSource::EXTERNAL_POLICY, base::DoNothing()));
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
index abc4cea..151d540 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
@@ -140,7 +140,7 @@
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
     web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(browser()->profile()));
+        WebAppProvider::GetForTest(browser()->profile()));
   }
 
   void TearDownOnMainThread() override {
@@ -459,7 +459,7 @@
   void SetUpOnMainThread() override {
     extensions::ExtensionBrowserTest::SetUpOnMainThread();
     web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(browser()->profile()));
+        WebAppProvider::GetForTest(browser()->profile()));
   }
   void TearDownOnMainThread() override {
     ResetInterceptor();
@@ -1171,7 +1171,8 @@
   auto install_info = std::make_unique<WebAppInstallInfo>();
   install_info->start_url = user_app_start_url;
   install_info->title = u"Test user app";
-  AppId user_app_id = test::InstallWebApp(profile(), std::move(install_info));
+  AppId user_app_id =
+      web_app::test::InstallWebApp(profile(), std::move(install_info));
 
   // Ensure the UI receives these apps.
   proxy->FlushMojoCallsForTesting();
diff --git a/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc
index ed2efaa..03f457a2 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_migration_browsertest.cc
@@ -103,8 +103,7 @@
     SetUpExtensionTestExternalProvider();
 
     extensions::ExtensionBrowserTest::SetUpOnMainThread();
-    web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(profile()));
+    web_app::test::WaitUntilReady(WebAppProvider::GetForTest(profile()));
   }
 
   std::unique_ptr<net::test_server::HttpResponse> RequestHandlerOverride(
diff --git a/chrome/browser/web_applications/test/fake_web_app_ui_manager.h b/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
index d005fb7..205246b 100644
--- a/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
+++ b/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
@@ -56,7 +56,7 @@
       const SkBitmap& old_icon,
       const SkBitmap& new_icon,
       content::WebContents* web_contents,
-      web_app::AppIdentityDialogCallback callback) override {}
+      AppIdentityDialogCallback callback) override {}
 
  private:
   std::map<AppId, size_t> app_id_to_num_windows_map_;
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
index 0bf28b7..c7646c3b 100644
--- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -96,7 +96,7 @@
   DCHECK(provider);
   WaitUntilReady(provider);
   provider->command_manager().ScheduleCommand(
-      std::make_unique<web_app::InstallFromInfoCommand>(
+      std::make_unique<InstallFromInfoCommand>(
           std::move(web_app_info), &provider->install_finalizer(),
           overwrite_existing_manifest_fields, install_source,
           base::BindLambdaForTesting([&](const AppId& installed_app_id,
diff --git a/chrome/browser/web_applications/test/web_app_test_observers.cc b/chrome/browser/web_applications/test/web_app_test_observers.cc
index dcd285c8..a2a6e1e0 100644
--- a/chrome/browser/web_applications/test/web_app_test_observers.cc
+++ b/chrome/browser/web_applications/test/web_app_test_observers.cc
@@ -166,7 +166,7 @@
 }
 
 void WebAppTestRegistryObserverAdapter::OnWebAppLastBadgingTimeChanged(
-    const web_app::AppId& app_id,
+    const AppId& app_id,
     const base::Time& time) {
   if (app_last_badging_time_changed_delegate_)
     app_last_badging_time_changed_delegate_.Run(app_id, time);
diff --git a/chrome/browser/web_applications/test/web_app_test_observers.h b/chrome/browser/web_applications/test/web_app_test_observers.h
index 53ee444..0fc3863 100644
--- a/chrome/browser/web_applications/test/web_app_test_observers.h
+++ b/chrome/browser/web_applications/test/web_app_test_observers.h
@@ -132,7 +132,7 @@
   void OnWebAppsWillBeUpdatedFromSync(
       const std::vector<const WebApp*>& new_apps_state) override;
   void OnWebAppProfileWillBeDeleted(const AppId& app_id) override;
-  void OnWebAppLastBadgingTimeChanged(const web_app::AppId& app_id,
+  void OnWebAppLastBadgingTimeChanged(const AppId& app_id,
                                       const base::Time& time) override;
   void OnWebAppProtocolSettingsChanged() override;
 
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc
index b5b5b61..492d7ce 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -656,7 +656,7 @@
                        const GURL& url,
                        const ExternalInstallSource& source) {
   ScopedRegistryUpdate update(sync_bridge);
-  web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+  WebApp* app_to_update = update->UpdateApp(app_id);
   DCHECK(app_to_update);
 
   // Adding external app data (source and URL) to web_app DB.
@@ -677,7 +677,7 @@
                                      bool is_placeholder) {
   ScopedRegistryUpdate update(sync_bridge);
   ExternallyInstalledWebAppPrefs prefs(pref_service);
-  web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+  WebApp* app_to_update = update->UpdateApp(app_id);
   DCHECK(app_to_update);
 
   // Adding install_url, source and placeholder information to the web_app DB.
diff --git a/chrome/browser/web_applications/web_app_constants.cc b/chrome/browser/web_applications/web_app_constants.cc
index cc36df79..bfd13eb 100644
--- a/chrome/browser/web_applications/web_app_constants.cc
+++ b/chrome/browser/web_applications/web_app_constants.cc
@@ -164,14 +164,13 @@
   }
 }
 
-apps::RunOnOsLoginMode ConvertOsLoginMode(
-    web_app::RunOnOsLoginMode login_mode) {
+apps::RunOnOsLoginMode ConvertOsLoginMode(RunOnOsLoginMode login_mode) {
   switch (login_mode) {
-    case web_app::RunOnOsLoginMode::kWindowed:
+    case RunOnOsLoginMode::kWindowed:
       return apps::RunOnOsLoginMode::kWindowed;
-    case web_app::RunOnOsLoginMode::kNotRun:
+    case RunOnOsLoginMode::kNotRun:
       return apps::RunOnOsLoginMode::kNotRun;
-    case web_app::RunOnOsLoginMode::kMinimized:
+    case RunOnOsLoginMode::kMinimized:
       return apps::RunOnOsLoginMode::kUnknown;
   }
 }
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h
index 41c78363..54cd50c 100644
--- a/chrome/browser/web_applications/web_app_constants.h
+++ b/chrome/browser/web_applications/web_app_constants.h
@@ -199,9 +199,9 @@
 
 std::string RunOnOsLoginModeToString(RunOnOsLoginMode mode);
 
-// Converts RunOnOsLoginMode from web_app::RunOnOsLoginMode to
+// Converts RunOnOsLoginMode from RunOnOsLoginMode to
 // apps::RunOnOsLoginMode.
-apps::RunOnOsLoginMode ConvertOsLoginMode(web_app::RunOnOsLoginMode login_mode);
+apps::RunOnOsLoginMode ConvertOsLoginMode(RunOnOsLoginMode login_mode);
 
 // Number of times IPH can be ignored for this app before it's muted.
 constexpr int kIphMuteAfterConsecutiveAppSpecificIgnores = 3;
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index ebfa0ab..5764eb4 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -214,20 +214,20 @@
 
 WebAppManagement::Type ProtoToWebAppManagement(WebAppManagementProto type) {
   switch (type) {
-    case web_app::WebAppManagementProto::WEBAPPMANAGEMENT_UNSPECIFIED:
+    case WebAppManagementProto::WEBAPPMANAGEMENT_UNSPECIFIED:
       NOTREACHED();
       [[fallthrough]];
-    case web_app::WebAppManagementProto::SYSTEM:
+    case WebAppManagementProto::SYSTEM:
       return WebAppManagement::Type::kSystem;
-    case web_app::WebAppManagementProto::POLICY:
+    case WebAppManagementProto::POLICY:
       return WebAppManagement::Type::kPolicy;
-    case web_app::WebAppManagementProto::SUBAPP:
+    case WebAppManagementProto::SUBAPP:
       return WebAppManagement::Type::kSubApp;
-    case web_app::WebAppManagementProto::WEBAPPSTORE:
+    case WebAppManagementProto::WEBAPPSTORE:
       return WebAppManagement::Type::kWebAppStore;
-    case web_app::WebAppManagementProto::SYNC:
+    case WebAppManagementProto::SYNC:
       return WebAppManagement::Type::kSync;
-    case web_app::WebAppManagementProto::DEFAULT:
+    case WebAppManagementProto::DEFAULT:
       return WebAppManagement::Type::kDefault;
   }
 }
@@ -235,17 +235,17 @@
 WebAppManagementProto WebAppManagementToProto(WebAppManagement::Type type) {
   switch (type) {
     case WebAppManagement::Type::kSystem:
-      return web_app::WebAppManagementProto::SYSTEM;
+      return WebAppManagementProto::SYSTEM;
     case WebAppManagement::Type::kPolicy:
-      return web_app::WebAppManagementProto::POLICY;
+      return WebAppManagementProto::POLICY;
     case WebAppManagement::Type::kSubApp:
-      return web_app::WebAppManagementProto::SUBAPP;
+      return WebAppManagementProto::SUBAPP;
     case WebAppManagement::Type::kWebAppStore:
-      return web_app::WebAppManagementProto::WEBAPPSTORE;
+      return WebAppManagementProto::WEBAPPSTORE;
     case WebAppManagement::Type::kSync:
-      return web_app::WebAppManagementProto::SYNC;
+      return WebAppManagementProto::SYNC;
     case WebAppManagement::Type::kDefault:
-      return web_app::WebAppManagementProto::DEFAULT;
+      return WebAppManagementProto::DEFAULT;
   }
 }
 
diff --git a/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc b/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
index d45d51df..178b4763 100644
--- a/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
@@ -51,7 +51,7 @@
   void SetUpOnMainThread() override {
     Profile* profile = browser()->profile();
     app_service_test_.SetUp(profile);
-    web_app::test::WaitUntilReady(web_app::WebAppProvider::GetForTest(profile));
+    web_app::test::WaitUntilReady(WebAppProvider::GetForTest(profile));
   }
 
   // InProcessBrowserTest:
@@ -92,7 +92,7 @@
 
     auto* provider = WebAppProvider::GetForTest(browser()->profile());
     provider->command_manager().ScheduleCommand(
-        std::make_unique<web_app::InstallFromInfoCommand>(
+        std::make_unique<InstallFromInfoCommand>(
             std::move(install_info), &provider->install_finalizer(),
             /*overwrite_existing_manifest_fields=*/false,
             webapps::WebappInstallSource::OMNIBOX_INSTALL_ICON,
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc
index aef5d1c..7d74899d 100644
--- a/chrome/browser/web_applications/web_app_install_finalizer.cc
+++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -566,7 +566,7 @@
       finalize_options.add_to_applications_menu;
 
   {
-    web_app::RunOnOsLoginMode current_mode =
+    RunOnOsLoginMode current_mode =
         registrar_->GetAppRunOnOsLoginMode(app_id).value;
     hooks_options.os_hooks[OsHookType::kRunOnOsLogin] =
         current_mode == RunOnOsLoginMode::kWindowed;
@@ -595,7 +595,7 @@
 void WebAppInstallFinalizer::OnInstallHooksFinished(
     InstallFinalizedCallback callback,
     AppId app_id,
-    web_app::OsHooksErrors os_hooks_errors) {
+    OsHooksErrors os_hooks_errors) {
   auto joined = std::move(callback).Then(
       base::BindOnce(&WebAppInstallFinalizer::NotifyWebAppInstalledWithOsHooks,
                      weak_ptr_factory_.GetWeakPtr(), app_id));
@@ -650,7 +650,7 @@
     InstallFinalizedCallback callback,
     AppId app_id,
     std::string old_name,
-    web_app::OsHooksErrors os_hooks_errors) {
+    OsHooksErrors os_hooks_errors) {
   install_manager_->NotifyWebAppManifestUpdated(app_id, old_name);
 
   std::move(callback).Run(
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.h b/chrome/browser/web_applications/web_app_install_finalizer.h
index a57c7c0a..6721e6b 100644
--- a/chrome/browser/web_applications/web_app_install_finalizer.h
+++ b/chrome/browser/web_applications/web_app_install_finalizer.h
@@ -197,7 +197,7 @@
 
   void OnInstallHooksFinished(InstallFinalizedCallback callback,
                               AppId app_id,
-                              web_app::OsHooksErrors os_hooks_errors);
+                              OsHooksErrors os_hooks_errors);
   void NotifyWebAppInstalledWithOsHooks(AppId app_id);
 
   bool ShouldUpdateOsHooks(const AppId& app_id);
@@ -213,7 +213,7 @@
   void OnUpdateHooksFinished(InstallFinalizedCallback callback,
                              AppId app_id,
                              std::string old_name,
-                             web_app::OsHooksErrors os_hooks_errors);
+                             OsHooksErrors os_hooks_errors);
 
   // Returns a value indicating whether the file handlers registered with the OS
   // should be updated. Used to avoid unnecessary updates. TODO(estade): why
diff --git a/chrome/browser/web_applications/web_app_install_finalizer_unittest.cc b/chrome/browser/web_applications/web_app_install_finalizer_unittest.cc
index b81974d..fca7e20 100644
--- a/chrome/browser/web_applications/web_app_install_finalizer_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_finalizer_unittest.cc
@@ -69,8 +69,7 @@
 
  private:
   bool web_app_manifest_updated_called_ = false;
-  base::ScopedObservation<web_app::WebAppInstallManager,
-                          web_app::WebAppInstallManagerObserver>
+  base::ScopedObservation<WebAppInstallManager, WebAppInstallManagerObserver>
       install_manager_observation_{this};
 };
 
@@ -250,10 +249,9 @@
   FinalizeInstallResult result = AwaitFinalizeInstall(*info, options);
   base::RunLoop runloop;
   finalizer().FinalizeUpdate(
-      *info,
-      base::BindLambdaForTesting(
-          [&](const web_app::AppId& app_id, webapps::InstallResultCode code,
-              web_app::OsHooksErrors os_hooks_errors) { runloop.Quit(); }));
+      *info, base::BindLambdaForTesting(
+                 [&](const AppId& app_id, webapps::InstallResultCode code,
+                     OsHooksErrors os_hooks_errors) { runloop.Quit(); }));
   runloop.Run();
   EXPECT_TRUE(install_manager_observer_->web_app_manifest_updated_called());
 }
@@ -385,10 +383,9 @@
 
   base::RunLoop runloop;
   finalizer().FinalizeUpdate(
-      *info,
-      base::BindLambdaForTesting([&](const web_app::AppId& app_id,
-                                     webapps::InstallResultCode code,
-                                     web_app::OsHooksErrors os_hooks_errors) {
+      *info, base::BindLambdaForTesting([&](const AppId& app_id,
+                                            webapps::InstallResultCode code,
+                                            OsHooksErrors os_hooks_errors) {
         EXPECT_EQ(webapps::InstallResultCode::kSuccessAlreadyInstalled, code);
         EXPECT_TRUE(os_hooks_errors.none());
         runloop.Quit();
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
index 4633b845..bb2c428 100644
--- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -232,8 +232,7 @@
         base::BindLambdaForTesting(
             [](content::WebContents* initiator_web_contents,
                std::unique_ptr<WebAppInstallInfo> web_app_info,
-               web_app::WebAppInstallationAcceptanceCallback
-                   acceptance_callback) {
+               WebAppInstallationAcceptanceCallback acceptance_callback) {
               std::move(acceptance_callback)
                   .Run(/*user_accepted=*/true, std::move(web_app_info));
             }),
@@ -254,16 +253,15 @@
       webapps::WebappInstallSource install_source) {
     InstallResult result;
     base::RunLoop run_loop;
-    command_manager().ScheduleCommand(
-        std::make_unique<web_app::InstallFromInfoCommand>(
-            std::move(install_info), &finalizer(),
-            overwrite_existing_manifest_fields, install_source,
-            base::BindLambdaForTesting([&](const AppId& installed_app_id,
-                                           webapps::InstallResultCode code) {
-              result.app_id = installed_app_id;
-              result.code = code;
-              run_loop.Quit();
-            })));
+    command_manager().ScheduleCommand(std::make_unique<InstallFromInfoCommand>(
+        std::move(install_info), &finalizer(),
+        overwrite_existing_manifest_fields, install_source,
+        base::BindLambdaForTesting([&](const AppId& installed_app_id,
+                                       webapps::InstallResultCode code) {
+          result.app_id = installed_app_id;
+          result.code = code;
+          run_loop.Quit();
+        })));
 
     run_loop.Run();
     return result;
diff --git a/chrome/browser/web_applications/web_app_internals_browsertest.cc b/chrome/browser/web_applications/web_app_internals_browsertest.cc
index 460f145..fd72576 100644
--- a/chrome/browser/web_applications/web_app_internals_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_internals_browsertest.cc
@@ -81,8 +81,7 @@
   }
 
   void SetUpOnMainThread() override {
-    web_app::test::WaitUntilReady(
-        web_app::WebAppProvider::GetForTest(browser()->profile()));
+    test::WaitUntilReady(WebAppProvider::GetForTest(browser()->profile()));
     InProcessBrowserTest::SetUpOnMainThread();
   }
 
@@ -174,8 +173,7 @@
 
 IN_PROC_BROWSER_TEST_F(WebAppInternalsBrowserTest,
                        InstallManagerErrorsPersist) {
-  web_app::test::WaitUntilReady(
-      web_app::WebAppProvider::GetForTest(browser()->profile()));
+  test::WaitUntilReady(WebAppProvider::GetForTest(browser()->profile()));
 
   ASSERT_TRUE(GetProvider().install_manager().error_log());
   ASSERT_EQ(1u, GetProvider().install_manager().error_log()->size());
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc
index 82db23f..ec2fd9ab 100644
--- a/chrome/browser/web_applications/web_app_registrar.cc
+++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -574,8 +574,8 @@
 
   auto* web_app = GetAppById(app_id);
   DCHECK(web_app);
-  return !web_app->HasOnlySource(web_app::WebAppManagement::kDefault) ||
-         GetAppEffectiveDisplayMode(app_id) != web_app::DisplayMode::kBrowser;
+  return !web_app->HasOnlySource(WebAppManagement::kDefault) ||
+         GetAppEffectiveDisplayMode(app_id) != DisplayMode::kBrowser;
 }
 
 bool WebAppRegistrar::IsIsolated(const AppId& app_id) const {
@@ -752,7 +752,7 @@
 }
 
 bool WebAppRegistrar::IsAppFileHandlerPermissionBlocked(
-    const web_app::AppId& app_id) const {
+    const AppId& app_id) const {
   auto* web_app = GetAppById(app_id);
   if (!web_app)
     return false;
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h
index 0ce421c..4c9a2968 100644
--- a/chrome/browser/web_applications/web_app_registrar.h
+++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -186,7 +186,7 @@
   const std::string* GetAppLaunchQueryParams(const AppId& app_id) const;
   const apps::ShareTarget* GetAppShareTarget(const AppId& app_id) const;
   const apps::FileHandlers* GetAppFileHandlers(const AppId& app_id) const;
-  bool IsAppFileHandlerPermissionBlocked(const web_app::AppId& app_id) const;
+  bool IsAppFileHandlerPermissionBlocked(const AppId& app_id) const;
   bool IsIsolated(const AppId& app_id) const;
 
   // Returns the state of the File Handling API for the given app.
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc
index 0112251..9511a39 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -352,7 +352,7 @@
   // examine stale data.
   {
     ScopedRegistryUpdate update(this);
-    web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+    WebApp* app_to_update = update->UpdateApp(app_id);
     base::flat_set<std::string> protocol_handlers(
         app_to_update->allowed_launch_protocols());
 
@@ -372,7 +372,7 @@
   // examine stale data.
   {
     ScopedRegistryUpdate update(this);
-    web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+    WebApp* app_to_update = update->UpdateApp(app_id);
     base::flat_set<std::string> protocol_handlers(
         app_to_update->allowed_launch_protocols());
     protocol_handlers.erase(protocol_scheme);
@@ -390,7 +390,7 @@
   // examine stale data.
   {
     ScopedRegistryUpdate update(this);
-    web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+    WebApp* app_to_update = update->UpdateApp(app_id);
     base::flat_set<std::string> protocol_handlers(
         app_to_update->disallowed_launch_protocols());
 
@@ -410,7 +410,7 @@
   // examine stale data.
   {
     ScopedRegistryUpdate update(this);
-    web_app::WebApp* app_to_update = update->UpdateApp(app_id);
+    WebApp* app_to_update = update->UpdateApp(app_id);
     base::flat_set<std::string> protocol_handlers(
         app_to_update->disallowed_launch_protocols());
     protocol_handlers.erase(protocol_scheme);
diff --git a/chrome/browser/web_applications/web_app_translation_manager_unittest.cc b/chrome/browser/web_applications/web_app_translation_manager_unittest.cc
index f014b9fb..0d64ddf 100644
--- a/chrome/browser/web_applications/web_app_translation_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_translation_manager_unittest.cc
@@ -231,14 +231,14 @@
   app_info->translations = translations;
 
   // Install app
-  AppId app_id = web_app::test::InstallWebApp(profile(), std::move(app_info));
+  AppId app_id = test::InstallWebApp(profile(), std::move(app_info));
 
   // Check translations are stored
   EXPECT_EQ(provider().translation_manager().GetTranslatedName(app_id),
             item1.name);
 
   // Uninstall app
-  web_app::test::UninstallWebApp(profile(), app_id);
+  test::UninstallWebApp(profile(), app_id);
 
   // Check translations were deleted
   EXPECT_EQ(provider().translation_manager().GetTranslatedName(app_id),
diff --git a/chrome/browser/web_applications/web_app_ui_manager.h b/chrome/browser/web_applications/web_app_ui_manager.h
index b16bffd..cb8779c 100644
--- a/chrome/browser/web_applications/web_app_ui_manager.h
+++ b/chrome/browser/web_applications/web_app_ui_manager.h
@@ -106,7 +106,7 @@
       const SkBitmap& old_icon,
       const SkBitmap& new_icon,
       content::WebContents* web_contents,
-      web_app::AppIdentityDialogCallback callback) = 0;
+      AppIdentityDialogCallback callback) = 0;
 
  private:
   base::ObserverList<WebAppUiManagerObserver> observers_;
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index 10def68..d814e93 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -175,14 +175,13 @@
     content::RenderFrameHost* render_frame_host,
     content::BrowserContext* browser_context) {
   Profile* profile = Profile::FromBrowserContext(browser_context);
-  web_app::WebAppProvider* web_app_provider =
-      web_app::WebAppProvider::GetForWebApps(profile);
+  WebAppProvider* web_app_provider = WebAppProvider::GetForWebApps(profile);
   if (web_app_provider == nullptr) {
     return nullptr;
   }
 
-  web_app::WebAppRegistrar& web_app_registrar = web_app_provider->registrar();
-  const absl::optional<web_app::AppId> app_id =
+  WebAppRegistrar& web_app_registrar = web_app_provider->registrar();
+  const absl::optional<AppId> app_id =
       web_app_registrar.FindAppWithUrlInScope(url);
   if (!app_id.has_value()) {
     return nullptr;
diff --git a/chrome/browser/web_applications/web_app_utils.h b/chrome/browser/web_applications/web_app_utils.h
index 467e01c..c2ae4f0 100644
--- a/chrome/browser/web_applications/web_app_utils.h
+++ b/chrome/browser/web_applications/web_app_utils.h
@@ -92,7 +92,7 @@
 // tool/metrics/histograms/histograms.xml: "SystemWebAppProfileCategory".
 std::string GetProfileCategoryForLogging(Profile* profile);
 
-// Returns true if the WebApp should have `web_app::WebAppChromeOsData()`.
+// Returns true if the WebApp should have `WebAppChromeOsData()`.
 bool IsChromeOsDataMandatory();
 
 // Returns true if sync should install web apps locally by default.
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc b/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
index 5ac8ec5..a5083ab 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
@@ -4,19 +4,47 @@
 
 #include "chrome/browser/webid/federated_identity_account_keyed_permission_context.h"
 
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/content_settings/core/common/content_settings_types.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 namespace {
 const char kAccountIdsKey[] = "account-ids";
+const char kRpRequesterKey[] = "rp-requester";
+const char kRpEmbedderKey[] = "rp-embedder";
 
 base::Value::List* ExtractAccountList(base::Value& value) {
   return value.GetDict().FindList(kAccountIdsKey);
 }
+
+std::string BuildKey(const absl::optional<std::string>& relying_party_requester,
+                     const absl::optional<std::string>& relying_party_embedder,
+                     const std::string& identity_provider) {
+  if (relying_party_requester && relying_party_embedder &&
+      *relying_party_requester != *relying_party_embedder) {
+    return base::StringPrintf("%s<%s", identity_provider.c_str(),
+                              relying_party_embedder->c_str());
+  }
+  // Use `identity_provider` as the key when
+  // `relying_party_requester` == `relying_party_embedder` for the sake of
+  // backwards compatibility with permissions stored prior to addition of
+  // `relying_party_embedder` key.
+  return identity_provider;
+}
+
+std::string BuildKey(const url::Origin& relying_party_requester,
+                     const url::Origin& relying_party_embedder,
+                     const url::Origin& identity_provider) {
+  return BuildKey(relying_party_requester.Serialize(),
+                  relying_party_embedder.Serialize(),
+                  identity_provider.Serialize());
+}
+
 }  // namespace
 
 FederatedIdentityAccountKeyedPermissionContext::
@@ -31,15 +59,17 @@
       idp_origin_key_(idp_origin_key) {}
 
 bool FederatedIdentityAccountKeyedPermissionContext::HasPermission(
-    const url::Origin& relying_party,
+    const url::Origin& relying_party_requester,
+    const url::Origin& relying_party_embedder,
     const url::Origin& identity_provider,
     const std::string& account_id) {
   // TODO(crbug.com/1334019): This is currently origin-bound, but we would like
   // this grant to apply at the 'site' (aka eTLD+1) level. We should override
   // GetGrantedObject to find a grant that matches the RP's site rather
   // than origin, and also ensure that duplicate sites cannot be added.
-  const std::string key = identity_provider.Serialize();
-  auto granted_object = GetGrantedObject(relying_party, key);
+  std::string key = BuildKey(relying_party_requester, relying_party_embedder,
+                             identity_provider);
+  auto granted_object = GetGrantedObject(relying_party_requester, key);
 
   if (!granted_object)
     return false;
@@ -55,38 +85,46 @@
 }
 
 void FederatedIdentityAccountKeyedPermissionContext::GrantPermission(
-    const url::Origin& relying_party,
+    const url::Origin& relying_party_requester,
+    const url::Origin& relying_party_embedder,
     const url::Origin& identity_provider,
     const std::string& account_id) {
-  if (HasPermission(relying_party, identity_provider, account_id))
+  if (HasPermission(relying_party_requester, relying_party_embedder,
+                    identity_provider, account_id))
     return;
 
-  std::string idp_string = identity_provider.Serialize();
-  const auto granted_object = GetGrantedObject(relying_party, idp_string);
+  std::string key = BuildKey(relying_party_requester, relying_party_embedder,
+                             identity_provider);
+  const auto granted_object = GetGrantedObject(relying_party_requester, key);
   if (granted_object) {
     // There is an existing account so update its account list rather than
     // creating a new entry.
     base::Value new_object = granted_object->value.Clone();
     base::Value::List* new_object_list = ExtractAccountList(new_object);
     new_object_list->Append(account_id);
-    UpdateObjectPermission(relying_party, granted_object->value,
+    UpdateObjectPermission(relying_party_requester, granted_object->value,
                            std::move(new_object));
   } else {
     base::Value::Dict new_object;
-    new_object.Set(idp_origin_key_, idp_string);
+    new_object.Set(kRpRequesterKey, relying_party_requester.Serialize());
+    new_object.Set(kRpEmbedderKey, relying_party_embedder.Serialize());
+    new_object.Set(idp_origin_key_, identity_provider.Serialize());
     base::Value::List account_list;
     account_list.Append(account_id);
     new_object.Set(kAccountIdsKey, base::Value(std::move(account_list)));
-    GrantObjectPermission(relying_party, base::Value(std::move(new_object)));
+    GrantObjectPermission(relying_party_requester,
+                          base::Value(std::move(new_object)));
   }
 }
 
 void FederatedIdentityAccountKeyedPermissionContext::RevokePermission(
-    const url::Origin& relying_party,
+    const url::Origin& relying_party_requester,
+    const url::Origin& relying_party_embedder,
     const url::Origin& identity_provider,
     const std::string& account_id) {
-  std::string idp_string = identity_provider.Serialize();
-  const auto object = GetGrantedObject(relying_party, idp_string);
+  std::string key = BuildKey(relying_party_requester, relying_party_embedder,
+                             identity_provider);
+  const auto object = GetGrantedObject(relying_party_requester, key);
   // TODO(crbug.com/1311268): If the provided `account_id` does not match the
   // one we used when granting the permission, early return will leave an entry
   // in the storage that cannot be removed afterwards.
@@ -100,12 +138,29 @@
 
   // Remove the permission object if there is no account left.
   if (account_ids.size() == 0) {
-    RevokeObjectPermission(relying_party, idp_string);
+    RevokeObjectPermission(relying_party_requester, key);
   } else {
-    UpdateObjectPermission(relying_party, object->value, std::move(new_object));
+    UpdateObjectPermission(relying_party_requester, object->value,
+                           std::move(new_object));
   }
 }
 
+std::string FederatedIdentityAccountKeyedPermissionContext::GetKeyForObject(
+    const base::Value& object) {
+  DCHECK(IsValidObject(object));
+  const std::string* rp_requester_origin =
+      object.GetDict().FindString(kRpRequesterKey);
+  const std::string* rp_embedder_origin =
+      object.GetDict().FindString(kRpEmbedderKey);
+  const std::string* idp_origin = object.GetDict().FindString(idp_origin_key_);
+  return BuildKey(
+      rp_requester_origin ? absl::optional<std::string>(*rp_requester_origin)
+                          : absl::nullopt,
+      rp_embedder_origin ? absl::optional<std::string>(*rp_embedder_origin)
+                         : absl::nullopt,
+      *idp_origin);
+}
+
 bool FederatedIdentityAccountKeyedPermissionContext::IsValidObject(
     const base::Value& object) {
   return object.is_dict() && object.FindStringKey(idp_origin_key_);
@@ -117,9 +172,3 @@
   DCHECK(IsValidObject(object));
   return base::UTF8ToUTF16(*object.FindStringKey(idp_origin_key_));
 }
-
-std::string FederatedIdentityAccountKeyedPermissionContext::GetKeyForObject(
-    const base::Value& object) {
-  DCHECK(IsValidObject(object));
-  return std::string(*object.FindStringKey(idp_origin_key_));
-}
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context.h b/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
index 4a8ea6d..62f422d 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
@@ -33,29 +33,35 @@
   FederatedIdentityAccountKeyedPermissionContext& operator=(
       const FederatedIdentityAccountKeyedPermissionContext&) = delete;
 
-  // Returns whether there is an existing permission for the (relying_party,
-  // identity_provider, account_id) tuple.
-  bool HasPermission(const url::Origin& relying_party,
+  // Returns whether there is an existing permission for the
+  // (relying_party_requester, relying_party_embedder, identity_provider,
+  // account_id) tuple.
+  bool HasPermission(const url::Origin& relying_party_requester,
+                     const url::Origin& relying_party_embedder,
                      const url::Origin& identity_provider,
                      const std::string& account_id);
 
-  // Grants permission for the (relying_party, identity_provider, account_id)
-  // tuple.
-  void GrantPermission(const url::Origin& relying_party,
+  // Grants permission for the (relying_party_requester, relying_party_embedder,
+  // identity_provider, account_id) tuple.
+  void GrantPermission(const url::Origin& relying_party_requester,
+                       const url::Origin& relying_party_embedder,
                        const url::Origin& identity_provider,
                        const std::string& account_id);
 
-  // Revokes previously-granted permission for the (relying_party,
-  // identity_provider, account_id) tuple.
-  void RevokePermission(const url::Origin& relying_party,
+  // Revokes previously-granted permission for the (relying_party_requester,
+  // relying_party_embedder, identity_provider, account_id) tuple.
+  void RevokePermission(const url::Origin& relying_party_requester,
+                        const url::Origin& relying_party_embedder,
                         const url::Origin& identity_provider,
                         const std::string& account_id);
 
+  // permissions::ObjectPermissionContextBase:
+  std::string GetKeyForObject(const base::Value& object) override;
+
  private:
   // permissions::ObjectPermissionContextBase:
   bool IsValidObject(const base::Value& object) override;
   std::u16string GetObjectDisplayName(const base::Value& object) override;
-  std::string GetKeyForObject(const base::Value& object) override;
 
   const std::string idp_origin_key_;
 };
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc b/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
index 71833db..66c9f40f 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
@@ -13,13 +13,19 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+namespace {
+
+const char kTestIdpOriginKey[] = "identity-provider";
+
+}
+
 class FederatedIdentityAccountKeyedPermissionContextTest
     : public testing::Test {
  public:
   FederatedIdentityAccountKeyedPermissionContextTest() {
     context_ = std::make_unique<FederatedIdentityAccountKeyedPermissionContext>(
         &profile_, ContentSettingsType::FEDERATED_IDENTITY_SHARING,
-        "identity-provider");
+        kTestIdpOriginKey);
   }
 
   void TearDown() override { context_.reset(); }
@@ -42,81 +48,207 @@
   TestingProfile profile_;
 };
 
+// Test that the key is identical reglardless of whether the permission was
+// stored using the old format (prior to the relying-party-embedder key being
+// added) or the new format.
 TEST_F(FederatedIdentityAccountKeyedPermissionContextTest,
-       GrantAndRevokeAccountSpecificGenericPermission) {
-  const auto rp = url::Origin::Create(GURL("https://rp.example"));
-  const auto idp = url::Origin::Create(GURL("https://idp.example"));
-  std::string account{"consetogo"};
+       VerifyKeyRequesterAndEmbedderIdentical) {
+  const url::Origin rp = url::Origin::Create(GURL("https://rp.example"));
+  const url::Origin idp = url::Origin::Create(GURL("https://idp.example"));
+  const std::string account("consetogo");
 
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account));
+  // Old Format
+  {
+    base::Value::Dict new_object;
+    new_object.Set(kTestIdpOriginKey, idp.Serialize());
+    base::Value::List account_list;
+    account_list.Append(account);
+    new_object.Set("account-ids", base::Value(std::move(account_list)));
+    context()->GrantObjectPermission(rp, base::Value(std::move(new_object)));
+  }
+  auto granted_objects = context()->GetAllGrantedObjects();
+  EXPECT_EQ(1u, granted_objects.size());
+  std::string key_old_format =
+      context()->GetKeyForObject(granted_objects[0]->value);
 
-  context()->GrantPermission(rp, idp, account);
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account));
+  // Cleanup
+  context()->RevokePermission(rp, rp, idp, account);
+  EXPECT_TRUE(context()->GetAllGrantedObjects().empty());
 
-  context()->RevokePermission(rp, idp, account);
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account));
+  // New format
+  context()->GrantPermission(rp, rp, idp, account);
+  granted_objects = context()->GetAllGrantedObjects();
+  EXPECT_EQ(1u, granted_objects.size());
+  std::string key_new_format =
+      context()->GetKeyForObject(granted_objects[0]->value);
+
+  EXPECT_EQ(key_old_format, key_new_format);
 }
 
-// Ensure the context can handle multiple accounts per RP/IdP origin.
-TEST_F(FederatedIdentityAccountKeyedPermissionContextTest,
-       GrantTwoAccountSpecificPermissionsAndRevokeThem) {
-  const auto rp = url::Origin::Create(GURL("https://rp.example"));
-  const auto idp = url::Origin::Create(GURL("https://idp.example"));
-  std::string account_a{"consetogo"};
-  std::string account_b{"woolwich"};
+// Test that '<' in the url::Origin parameters passed to
+// FederatedIdentityAccountKeyedPermissionContext::GrantPermission() are
+// escaped.
+// '<' is used as a separator in
+// FederatedIdentityAccountKeyedPermissionContextTest::GetKeyForObject().
+TEST_F(FederatedIdentityAccountKeyedPermissionContextTest, VerifyKeySeparator) {
+  const url::Origin rp = url::Origin::Create(GURL("https://rp<.example</<?<"));
+  const url::Origin idp =
+      url::Origin::Create(GURL("https://idp<.example</<?<"));
+  const url::Origin rp_embedder =
+      url::Origin::Create(GURL("https://rp-embedder<.example</<?<"));
+  const std::string account("consetogo");
 
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_a));
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_b));
-
-  context()->GrantPermission(rp, idp, account_a);
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account_a));
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_b));
-
-  context()->GrantPermission(rp, idp, account_b);
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account_a));
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account_b));
-
-  context()->RevokePermission(rp, idp, account_a);
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_a));
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account_b));
-
-  context()->RevokePermission(rp, idp, account_b);
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_a));
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account_b));
+  context()->GrantPermission(rp, rp_embedder, idp, account);
+  auto granted_objects = context()->GetAllGrantedObjects();
+  EXPECT_EQ(1u, granted_objects.size());
+  std::string key = context()->GetKeyForObject(granted_objects[0]->value);
+  EXPECT_EQ("https://idp%3C.example%3C<https://rp-embedder%3C.example%3C", key);
 }
 
-// Test granting permissions for multiple IDPs mapped to the same RP and
-// multiple RPs mapped to the same IDP.
+// Test calling
+// FederatedIdentityAccountKeyedPermissionContextTest::HasPermission() for
+// permissions stored with the pre-relying-party-embedder-format.
 TEST_F(FederatedIdentityAccountKeyedPermissionContextTest,
-       GrantPermissionsMultipleRpsMultipleIdps) {
-  const auto rp1 = url::Origin::Create(GURL("https://rp1.example"));
-  const auto rp2 = url::Origin::Create(GURL("https://rp2.example"));
-  const auto idp1 = url::Origin::Create(GURL("https://idp1.example"));
-  const auto idp2 = url::Origin::Create(GURL("https://idp2.example"));
+       CompatibleWithOldFormat) {
+  const url::Origin rp = url::Origin::Create(GURL("https://rp.example"));
+  const url::Origin idp1 = url::Origin::Create(GURL("https://idp1.example"));
+  const url::Origin idp2 = url::Origin::Create(GURL("https://idp2.example"));
+  const url::Origin other_origin =
+      url::Origin::Create(GURL("https://other.example"));
+  const std::string account_a("conestogo");
+  const std::string account_b("woolwich");
+  const std::string account_c("wellesley");
 
-  context()->GrantPermission(rp1, idp1, "consestogo");
-  context()->GrantPermission(rp1, idp2, "woolwich");
-  context()->GrantPermission(rp2, idp1, "wilmot");
+  {
+    base::Value::Dict new_object;
+    new_object.Set(kTestIdpOriginKey, idp1.Serialize());
+    base::Value::List account_list;
+    account_list.Append(account_a);
+    account_list.Append(account_b);
+    new_object.Set("account-ids", base::Value(std::move(account_list)));
+    context()->GrantObjectPermission(rp, base::Value(std::move(new_object)));
+  }
+  {
+    base::Value::Dict new_object;
+    new_object.Set(kTestIdpOriginKey, idp2.Serialize());
+    base::Value::List account_list;
+    account_list.Append(account_c);
+    new_object.Set("account-ids", base::Value(std::move(account_list)));
+    context()->GrantObjectPermission(rp, base::Value(std::move(new_object)));
+  }
 
-  EXPECT_EQ(3u, context()->GetAllGrantedObjects().size());
-  EXPECT_EQ(2u, context()->GetGrantedObjects(rp1).size());
-  EXPECT_EQ(1u, context()->GetGrantedObjects(rp2).size());
+  // Permissions in the old format should only be returned when
+  // relying-party-requester == relying-party-embedder.
+  EXPECT_TRUE(context()->HasPermission(rp, rp, idp1, account_a));
+  EXPECT_TRUE(context()->HasPermission(rp, rp, idp1, account_b));
+  EXPECT_TRUE(context()->HasPermission(rp, rp, idp2, account_c));
+  EXPECT_FALSE(context()->HasPermission(rp, other_origin, idp1, account_a));
+
+  EXPECT_FALSE(context()->HasPermission(rp, rp, idp1, account_c));
+}
+
+namespace {
+
+struct PermissionGrant {
+  url::Origin relying_party_requester;
+  url::Origin relying_party_embedder;
+  url::Origin identity_provider;
+  std::string account_id;
+};
+
+}  // anonymous namespace
+
+void TestGrantAndRevoke(FederatedIdentityAccountKeyedPermissionContext* context,
+                        const PermissionGrant& grant1,
+                        const PermissionGrant& grant2) {
+  context->GrantPermission(grant1.relying_party_requester,
+                           grant1.relying_party_embedder,
+                           grant1.identity_provider, grant1.account_id);
+
+  EXPECT_TRUE(context->HasPermission(
+      grant1.relying_party_requester, grant1.relying_party_embedder,
+      grant1.identity_provider, grant1.account_id));
+  EXPECT_FALSE(context->HasPermission(
+      grant2.relying_party_requester, grant2.relying_party_embedder,
+      grant2.identity_provider, grant2.account_id));
+
+  context->GrantPermission(grant2.relying_party_requester,
+                           grant2.relying_party_embedder,
+                           grant2.identity_provider, grant2.account_id);
+
+  EXPECT_TRUE(context->HasPermission(
+      grant1.relying_party_requester, grant1.relying_party_embedder,
+      grant1.identity_provider, grant1.account_id));
+  EXPECT_TRUE(context->HasPermission(
+      grant2.relying_party_requester, grant2.relying_party_embedder,
+      grant2.identity_provider, grant2.account_id));
+
+  context->RevokePermission(grant1.relying_party_requester,
+                            grant1.relying_party_embedder,
+                            grant1.identity_provider, grant1.account_id);
+  EXPECT_FALSE(context->HasPermission(
+      grant1.relying_party_requester, grant1.relying_party_embedder,
+      grant1.identity_provider, grant1.account_id));
+  EXPECT_TRUE(context->HasPermission(
+      grant2.relying_party_requester, grant2.relying_party_embedder,
+      grant2.identity_provider, grant2.account_id));
+
+  context->RevokePermission(grant2.relying_party_requester,
+                            grant2.relying_party_embedder,
+                            grant2.identity_provider, grant2.account_id);
+  EXPECT_FALSE(context->HasPermission(
+      grant1.relying_party_requester, grant1.relying_party_embedder,
+      grant1.identity_provider, grant1.account_id));
+  EXPECT_FALSE(context->HasPermission(
+      grant2.relying_party_requester, grant2.relying_party_embedder,
+      grant2.identity_provider, grant2.account_id));
+
+  EXPECT_TRUE(context->GetAllGrantedObjects().empty());
+}
+
+// Test granting and revoking a permission.
+TEST_F(FederatedIdentityAccountKeyedPermissionContextTest, GrantAndRevoke) {
+  const url::Origin rp_requester1 =
+      url::Origin::Create(GURL("https://rp1.example"));
+  const url::Origin rp_requester2 =
+      url::Origin::Create(GURL("https://rp2.example"));
+  const url::Origin rp_embedder1 =
+      url::Origin::Create(GURL("https://rp-embedder1.example"));
+  const url::Origin rp_embedder2 =
+      url::Origin::Create(GURL("https://rp-embedder2.example"));
+  const url::Origin idp1 = url::Origin::Create(GURL("https://idp1.example"));
+  const url::Origin idp2 = url::Origin::Create(GURL("https://idp2.example"));
+  const std::string account1("consetogo");
+  const std::string account2("woolwich");
+
+  TestGrantAndRevoke(context(), {rp_requester1, rp_embedder1, idp1, account1},
+                     {rp_requester2, rp_embedder1, idp1, account1});
+  TestGrantAndRevoke(context(), {rp_requester1, rp_embedder1, idp1, account1},
+                     {rp_requester1, rp_embedder2, idp1, account1});
+  TestGrantAndRevoke(context(), {rp_requester1, rp_embedder1, idp1, account1},
+                     {rp_requester1, rp_embedder1, idp2, account1});
+  TestGrantAndRevoke(context(), {rp_requester1, rp_embedder1, idp1, account1},
+                     {rp_requester1, rp_embedder1, idp1, account2});
 }
 
 // Test that granting a permission for an account, if the permission has already
 // been granted, is a noop.
 TEST_F(FederatedIdentityAccountKeyedPermissionContextTest,
        GrantPermissionForSameAccount) {
-  const auto rp = url::Origin::Create(GURL("https://rp.example"));
-  const auto idp = url::Origin::Create(GURL("https://idp.example"));
+  const url::Origin rp_requester =
+      url::Origin::Create(GURL("https://rp.example"));
+  const url::Origin rp_embedder =
+      url::Origin::Create(GURL("https://rp-embedder.example"));
+  const url::Origin idp = url::Origin::Create(GURL("https://idp.example"));
   std::string account{"consetogo"};
 
-  EXPECT_FALSE(context()->HasPermission(rp, idp, account));
+  context()->GrantPermission(rp_requester, rp_embedder, idp, account);
+  auto granted_objects1 = context()->GetAllGrantedObjects();
 
-  context()->GrantPermission(rp, idp, account);
-  context()->GrantPermission(rp, idp, account);
-  EXPECT_TRUE(context()->HasPermission(rp, idp, account));
-  auto granted_object = context()->GetGrantedObject(rp, idp.Serialize());
-  EXPECT_EQ(1u,
-            granted_object->value.GetDict().FindList("account-ids")->size());
+  context()->GrantPermission(rp_requester, rp_embedder, idp, account);
+  auto granted_objects2 = context()->GetAllGrantedObjects();
+
+  EXPECT_EQ(1u, granted_objects1.size());
+  EXPECT_EQ(1u, granted_objects2.size());
+  EXPECT_EQ(granted_objects1[0]->value, granted_objects2[0]->value);
 }
diff --git a/chrome/browser/webid/federated_identity_active_session_permission_context.cc b/chrome/browser/webid/federated_identity_active_session_permission_context.cc
index 48e6ca2..78ca5c9c90 100644
--- a/chrome/browser/webid/federated_identity_active_session_permission_context.cc
+++ b/chrome/browser/webid/federated_identity_active_session_permission_context.cc
@@ -31,19 +31,22 @@
     const url::Origin& relying_party,
     const url::Origin& identity_provider,
     const std::string& account_identifier) {
-  return HasPermission(relying_party, identity_provider, account_identifier);
+  return HasPermission(relying_party, relying_party, identity_provider,
+                       account_identifier);
 }
 
 void FederatedIdentityActiveSessionPermissionContext::GrantActiveSession(
     const url::Origin& relying_party,
     const url::Origin& identity_provider,
     const std::string& account_identifier) {
-  GrantPermission(relying_party, identity_provider, account_identifier);
+  GrantPermission(relying_party, relying_party, identity_provider,
+                  account_identifier);
 }
 
 void FederatedIdentityActiveSessionPermissionContext::RevokeActiveSession(
     const url::Origin& relying_party,
     const url::Origin& identity_provider,
     const std::string& account_identifier) {
-  RevokePermission(relying_party, identity_provider, account_identifier);
+  RevokePermission(relying_party, relying_party, identity_provider,
+                   account_identifier);
 }
diff --git a/chrome/browser/webid/federated_identity_sharing_permission_context.cc b/chrome/browser/webid/federated_identity_sharing_permission_context.cc
index b3737eb..4754788a 100644
--- a/chrome/browser/webid/federated_identity_sharing_permission_context.cc
+++ b/chrome/browser/webid/federated_identity_sharing_permission_context.cc
@@ -31,12 +31,13 @@
     const url::Origin& relying_party,
     const url::Origin& identity_provider,
     const std::string& account_id) {
-  return HasPermission(relying_party, identity_provider, account_id);
+  return HasPermission(relying_party, relying_party, identity_provider,
+                       account_id);
 }
 
 void FederatedIdentitySharingPermissionContext::GrantSharingPermission(
     const url::Origin& relying_party,
     const url::Origin& identity_provider,
     const std::string& account_id) {
-  GrantPermission(relying_party, identity_provider, account_id);
+  GrantPermission(relying_party, relying_party, identity_provider, account_id);
 }
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index d8ae4066..5718e2c 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1657216488-964c1af31a57f69ad7c96efc5ae8bf09b66ba8c5.profdata
+chrome-linux-main-1657259924-75056b5dbf99cb9107b9e64309591676138fb661.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index e4d2f12..9381ee8 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1657195044-bdc21327076ea0bf11bc33a0cd128af31cd79101.profdata
+chrome-mac-arm-main-1657238380-9cd2b6a4df342dbac3a2b1ff370f85d1f6d9ebf4.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index a634a3c..63fdc01e 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1657216488-3802952b982e7586a03ee3c25333016309d62186.profdata
+chrome-mac-main-1657238380-a69973cb64c57b47020c4d16e861893d5f07a9e8.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 4f3ba80..87bfc65 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1657216488-a8c5fdc01bcc3053840f6798709fd8f47271c897.profdata
+chrome-win32-main-1657249050-2276cbfd2eaf7dbdd2a6b6a9d2bc0069faaf03b3.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 2325736..2dfd825 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1657227512-e426bd1bd9cb69b8348eeedd880ebb38b296177d.profdata
+chrome-win64-main-1657249050-c50aa1d9b7e19b31fd9de89971d7075df40c84e8.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f4ed5a6..c68fed81 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2627,6 +2627,7 @@
 
     if (is_chromeos_lacros) {
       sources += [
+        "../browser/apps/app_service/webapk/webapk_utils_lacros_browsertest.cc",
         "../browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc",
         "../browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc",
         "../browser/chromeos/policy/dlp/dlp_content_manager_test_helper.cc",
@@ -2659,6 +2660,7 @@
         "//chromeos/ui/frame:test_support",
         "//components/account_manager_core:test_support",
         "//components/services/app_service/public/cpp:intents",
+        "//components/webapk:proto",
       ]
     }
 
@@ -4142,6 +4144,7 @@
         "//chromeos/ash/components/network/portal_detector",
         "//chromeos/ash/services/assistant:lib",
         "//chromeos/ash/services/assistant/public/cpp",
+        "//chromeos/ash/services/assistant/public/proto",
         "//chromeos/ash/services/cros_healthd/public/cpp",
         "//chromeos/components/onc:test_support",
         "//chromeos/components/quick_answers/public/cpp:cpp",
@@ -4158,7 +4161,6 @@
         "//chromeos/dbus/power",
         "//chromeos/login/login_state:test_support",
         "//chromeos/process_proxy",
-        "//chromeos/services/assistant/public/proto",
         "//chromeos/services/machine_learning/public/cpp:stub",
         "//chromeos/services/tts",
         "//chromeos/system",
@@ -5734,6 +5736,7 @@
     "//components/reporting/encryption:test_support",
     "//components/reporting/encryption:testing_primitives",
     "//components/reporting/encryption:verification",
+    "//components/reporting/resources:resource_interface",
     "//components/reporting/storage:storage_uploader_interface",
     "//components/reporting/storage:test_support",
     "//components/reporting/util:backoff_settings",
@@ -7281,6 +7284,7 @@
       "//chromeos/ash/components/assistant:buildflags",
       "//chromeos/ash/components/dbus/cicerone",
       "//chromeos/ash/components/dbus/concierge",
+      "//chromeos/ash/components/dbus/image_loader",
       "//chromeos/ash/components/dbus/seneschal",
       "//chromeos/ash/components/dbus/update_engine",
       "//chromeos/ash/components/dbus/update_engine:proto",
@@ -7297,7 +7301,6 @@
       "//chromeos/dbus/cros_disks",
       "//chromeos/dbus/debug_daemon",
       "//chromeos/dbus/hermes",
-      "//chromeos/dbus/image_loader",
       "//chromeos/dbus/permission_broker",
       "//chromeos/dbus/power",
       "//chromeos/dbus/shill",
diff --git a/chrome/test/data/extensions/api_test/offscreen/create_document/background.js b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/background.js
similarity index 71%
rename from chrome/test/data/extensions/api_test/offscreen/create_document/background.js
rename to chrome/test/data/extensions/api_test/offscreen/basic_document_management/background.js
index 920041fb..2177a1b 100644
--- a/chrome/test/data/extensions/api_test/offscreen/create_document/background.js
+++ b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/background.js
@@ -3,13 +3,18 @@
 // found in the LICENSE file.
 
 chrome.test.runTests([
-  async function createDocumentAndEnsureItExists() {
+  async function createDocumentAndEnsureItExistsAndThenClose() {
+    chrome.test.assertFalse(await chrome.offscreen.hasDocument());
+
     await chrome.offscreen.createDocument(
         {
           url: 'offscreen.html',
           reasons: ['TESTING'],
           justification: 'ignored'
         });
+
+    chrome.test.assertTrue(await chrome.offscreen.hasDocument());
+
     // Sanity check that the document exists and can be reached by passing a
     // message and expecting a reply. Note that general offscreen document
     // behavior is tested more in the OffscreenDocumentHost tests, so this is
@@ -22,6 +27,11 @@
           reply: 'offscreen reply',
         },
         reply);
+
+    // Close the document to tidy up for the next test.
+    await chrome.offscreen.closeDocument();
+    chrome.test.assertFalse(await chrome.offscreen.hasDocument());
+
     chrome.test.succeed();
   },
 ])
diff --git a/chrome/test/data/extensions/api_test/offscreen/create_document/manifest.json b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/manifest.json
similarity index 72%
rename from chrome/test/data/extensions/api_test/offscreen/create_document/manifest.json
rename to chrome/test/data/extensions/api_test/offscreen/basic_document_management/manifest.json
index 50152b2..d9f61da 100644
--- a/chrome/test/data/extensions/api_test/offscreen/create_document/manifest.json
+++ b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/manifest.json
@@ -1,5 +1,5 @@
 {
-  "name": "offscreen.createDocument test",
+  "name": "offscreen basic document management test",
   "version": "0.1",
   "manifest_version": 3,
   "permissions": ["offscreen"],
diff --git a/chrome/test/data/extensions/api_test/offscreen/create_document/offscreen.html b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/offscreen.html
similarity index 100%
rename from chrome/test/data/extensions/api_test/offscreen/create_document/offscreen.html
rename to chrome/test/data/extensions/api_test/offscreen/basic_document_management/offscreen.html
diff --git a/chrome/test/data/extensions/api_test/offscreen/create_document/offscreen.js b/chrome/test/data/extensions/api_test/offscreen/basic_document_management/offscreen.js
similarity index 100%
rename from chrome/test/data/extensions/api_test/offscreen/create_document/offscreen.js
rename to chrome/test/data/extensions/api_test/offscreen/basic_document_management/offscreen.js
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index fa56dc71..4613f20 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -430,6 +430,7 @@
   in_files = [
     "chrome_timeticks_test.ts",
     "color_provider_css_colors_test.ts",
+    "color_provider_css_colors_test_chromeos.ts",
     "cr_focus_row_behavior_test.ts",
     "resources/list_property_update_behavior_tests.ts",
     "resources/list_property_update_mixin_tests.ts",
diff --git a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
index 98050d2b..00addd20 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/local_images_element_test.ts
@@ -150,13 +150,19 @@
       'sets aria-selected attribute if image name matches currently selected',
       async () => {
         personalizationStore.data.wallpaper.local = {
-          images: wallpaperProvider.localImages,
-          data: wallpaperProvider.localImageData,
+          images: [
+            {path: '/test/LocalImage0.png'}, {path: '/test/LocalImage1.png'}
+          ],
+          data: {
+            '/test/LocalImage0.png': 'data://localimage0data',
+            '/test/LocalImage1.png': 'data://localimage1data',
+          },
         };
         // Done loading.
         personalizationStore.data.wallpaper.loading.local = {
           images: false,
-          data: {'LocalImage0.png': false, 'LocalImage1.png': false},
+          data:
+              {'/test/LocalImage0.png': false, '/test/LocalImage1.png': false},
         };
 
         localImagesElement = initElement(LocalImages, {hidden: false});
@@ -173,7 +179,7 @@
             image => image.getAttribute('aria-selected') === 'false'));
 
         personalizationStore.data.wallpaper.currentSelected = {
-          key: 'LocalImage1.png'
+          key: '/test/LocalImage1.png'
         };
         personalizationStore.notifyObservers();
 
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
index 0abbe50..e2abe57e 100644
--- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
+++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
@@ -774,7 +774,7 @@
       return image.assetId.toString();
     }
     if (isFilePath(image)) {
-      return image.path.substr(image.path.lastIndexOf('/') + 1);
+      return image.path;
     }
     assertNotReached('unknown wallpaper type');
   }
diff --git a/chrome/test/data/webui/color_provider_css_colors_browsertest.js b/chrome/test/data/webui/color_provider_css_colors_browsertest.js
index 2a8541f..e5aaca9 100644
--- a/chrome/test/data/webui/color_provider_css_colors_browsertest.js
+++ b/chrome/test/data/webui/color_provider_css_colors_browsertest.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+GEN('#include "build/chromeos_buildflags.h"');
 GEN('#include "content/public/test/browser_test.h"');
 
 var ColorProviderCSSColorsTest = class extends testing.Test {
@@ -32,3 +33,19 @@
 TEST_F('ColorProviderCSSColorsTest', 'All', function() {
   mocha.run();
 });
+
+var ColorProviderCSSColorsTestChromeOS =
+    class extends ColorProviderCSSColorsTest {
+  /** @override */
+  get browsePreload() {
+    return 'chrome://test/test_loader.html?module=color_provider_css_colors_test_chromeos.js';
+  }
+};
+
+GEN('#if BUILDFLAG(IS_CHROMEOS_ASH)');
+
+TEST_F('ColorProviderCSSColorsTestChromeOS', 'All', function() {
+  mocha.run();
+});
+
+GEN('#endif  // BUILDFLAG(IS_CHROMEOS_ASH)');
diff --git a/chrome/test/data/webui/color_provider_css_colors_test.ts b/chrome/test/data/webui/color_provider_css_colors_test.ts
index acc3f51..aa8d5e4 100644
--- a/chrome/test/data/webui/color_provider_css_colors_test.ts
+++ b/chrome/test/data/webui/color_provider_css_colors_test.ts
@@ -2,15 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {assertNotEquals} from './chai_assert.js';
+import {assertEquals, assertNotEquals} from './chai_assert.js';
 
 suite('ColorProviderCSSColorsTest', function() {
+  let link: HTMLLinkElement;
+  setup(() => {
+    link = document.createElement('link');
+    link.rel = 'stylesheet';
+    document.body.appendChild(link);
+  });
+
+  teardown(() => {
+    document.body.removeChild(link);
+  });
+
   test(
       'test ui side and chrome side color provider colors added to css stylesheet',
       function(done) {
-        const link = document.createElement('link');
-        link.rel = 'stylesheet';
-        link.href = 'chrome://theme/colors.css';
+        link.href = 'chrome://theme/colors.css?sets=ui,chrome';
         link.onload = function() {
           const style = getComputedStyle(document.body);
           // Check that we are able to query for a ui/ side color.
@@ -25,6 +34,22 @@
         link.onerror = function(e) {
           done(new Error('Error loading colors.css' + e));
         };
-        document.body.appendChild(link);
       });
+
+  test('test fetching ui color set only', function(done) {
+    link.href = 'chrome://theme/colors.css?sets=ui';
+    link.onload = function() {
+      const style = getComputedStyle(document.body);
+      // Check that we are able to query for a ui/ side color.
+      assertNotEquals('', style.getPropertyValue('--color-accent'));
+      // Check that we are not able to query for a chrome/ side color.
+      assertEquals(
+          '',
+          style.getPropertyValue('--color-app-menu-highlight-severity-low'));
+      done();
+    };
+    link.onerror = function(e) {
+      done(new Error('Error loading colors.css' + e));
+    };
+  });
 });
diff --git a/chrome/test/data/webui/color_provider_css_colors_test_chromeos.ts b/chrome/test/data/webui/color_provider_css_colors_test_chromeos.ts
new file mode 100644
index 0000000..eb74fb6c
--- /dev/null
+++ b/chrome/test/data/webui/color_provider_css_colors_test_chromeos.ts
@@ -0,0 +1,35 @@
+// 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 {assertNotEquals} from './chai_assert.js';
+
+suite('ColorProviderCSSColorsTest', function() {
+  let link: HTMLLinkElement;
+  setup(() => {
+    link = document.createElement('link');
+    link.rel = 'stylesheet';
+    document.body.appendChild(link);
+  });
+
+  teardown(() => {
+    document.body.removeChild(link);
+  });
+
+  test('test fetching chromeos color sets', function(done) {
+    link.href = 'chrome://theme/colors.css?sets=ref,sys,legacy';
+    link.onload = function() {
+      const style = getComputedStyle(document.body);
+      // Check that we are able to query for a cros.ref color.
+      assertNotEquals('', style.getPropertyValue('--cros-ref-primary100'));
+      // Check that we are able to query for a cros.sys color.
+      assertNotEquals('', style.getPropertyValue('--cros-sys-primary'));
+      // Check that we are able to query for a legacy semantic color.
+      assertNotEquals('', style.getPropertyValue('--cros-color-primary'));
+      done();
+    };
+    link.onerror = function(e) {
+      done(new Error('Error loading colors.css' + e));
+    };
+  });
+});
diff --git a/chrome/test/data/webui/cr_components/color_change_listener_test.ts b/chrome/test/data/webui/cr_components/color_change_listener_test.ts
index f0a3b62..9876c46e 100644
--- a/chrome/test/data/webui/cr_components/color_change_listener_test.ts
+++ b/chrome/test/data/webui/cr_components/color_change_listener_test.ts
@@ -8,7 +8,7 @@
 suite('ColorChangeListenerTest', () => {
   setup(() => {
     document.body.innerHTML =
-        '<link rel="stylesheet" href="chrome://theme/colors.css"/>';
+        '<link rel="stylesheet" href="chrome://theme/colors.css?sets=ui"/>';
   });
 
   test('CorrectlyUpdatesColorsStylesheetURL', async () => {
@@ -48,7 +48,7 @@
     // Handles the case where the link element exists but the attribute is
     // malformed.
     document.body.innerHTML =
-        '<link rel="stylesheet" bad_href="chrome://theme/colors.css"/>';
+        '<link rel="stylesheet" bad_href="chrome://theme/colors.css?sets=ui"/>';
     assertFalse(refreshColorCss());
 
     // Handles the case where the link element does not exist.
diff --git a/chrome/test/data/webui/webui_resource_browsertest.cc b/chrome/test/data/webui/webui_resource_browsertest.cc
index 5b908440..14d7176 100644
--- a/chrome/test/data/webui/webui_resource_browsertest.cc
+++ b/chrome/test/data/webui/webui_resource_browsertest.cc
@@ -65,17 +65,15 @@
   LoadTestUrl("i18n_process_css_test.html");
 }
 
-IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ListModuleTest) {
-  LoadTestUrl("?module=js/cr/ui/list_test.js");
-}
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, GridModuleTest) {
   LoadTestUrl("?module=js/cr/ui/grid_test.js");
 }
 
-// This test is Chrome OS only as the utils file it imports relies on
-// list_single_selection_model, which is only included on Chrome OS.
+IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ListModuleTest) {
+  LoadTestUrl("?module=js/cr/ui/list_test.js");
+}
+
 IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, ListSelectionModelModuleTest) {
   LoadTestUrl("?module=js/cr/ui/list_selection_model_test.js");
 }
diff --git a/chromeos/dbus/image_loader/BUILD.gn b/chromeos/ash/components/dbus/image_loader/BUILD.gn
similarity index 72%
rename from chromeos/dbus/image_loader/BUILD.gn
rename to chromeos/ash/components/dbus/image_loader/BUILD.gn
index 85ff21ea..b9c8c9c 100644
--- a/chromeos/dbus/image_loader/BUILD.gn
+++ b/chromeos/ash/components/dbus/image_loader/BUILD.gn
@@ -4,11 +4,12 @@
 
 import("//build/config/chromeos/ui_mode.gni")
 
-assert(is_chromeos_ash, "Non-Chrome-OS builds must not depend on //chromeos")
+assert(is_chromeos_ash,
+       "Non-Chrome-OS builds must not depend on //chromeos/ash")
 
 component("image_loader") {
-  output_name = "chromeos_image_loader"
-  defines = [ "IS_CHROMEOS_DBUS_IMAGE_LOADER_IMPL" ]
+  output_name = "ash_image_loader"
+  defines = [ "IS_ASH_DBUS_IMAGE_LOADER_IMPL" ]
   deps = [
     "//base",
     "//chromeos/dbus/common",
diff --git a/chromeos/dbus/image_loader/fake_image_loader_client.cc b/chromeos/ash/components/dbus/image_loader/fake_image_loader_client.cc
similarity index 97%
rename from chromeos/dbus/image_loader/fake_image_loader_client.cc
rename to chromeos/ash/components/dbus/image_loader/fake_image_loader_client.cc
index 150116f..9fcc741 100644
--- a/chromeos/dbus/image_loader/fake_image_loader_client.cc
+++ b/chromeos/ash/components/dbus/image_loader/fake_image_loader_client.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/image_loader/fake_image_loader_client.h"
+#include "chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h"
 
 #include <utility>
 
@@ -14,7 +14,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace chromeos {
+namespace ash {
 
 FakeImageLoaderClient::FakeImageLoaderClient() = default;
 
@@ -130,4 +130,4 @@
       base::BindOnce(std::move(callback), absl::make_optional(true)));
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chromeos/dbus/image_loader/fake_image_loader_client.h b/chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h
similarity index 87%
rename from chromeos/dbus/image_loader/fake_image_loader_client.h
rename to chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h
index 9109c13..7be51141 100644
--- a/chromeos/dbus/image_loader/fake_image_loader_client.h
+++ b/chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h
@@ -2,24 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
-#define CHROMEOS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
 
 #include <map>
 #include <set>
 #include <string>
 
 #include "base/component_export.h"
-#include "chromeos/dbus/image_loader/image_loader_client.h"
+#include "chromeos/ash/components/dbus/image_loader/image_loader_client.h"
 
 namespace base {
 class FilePath;
 }
 
-namespace chromeos {
+namespace ash {
 
 // A fake implementation of ImageLoaderClient. This class does nothing.
-class COMPONENT_EXPORT(CHROMEOS_DBUS_IMAGE_LOADER) FakeImageLoaderClient
+class COMPONENT_EXPORT(ASH_DBUS_IMAGE_LOADER) FakeImageLoaderClient
     : public ImageLoaderClient {
  public:
   FakeImageLoaderClient();
@@ -82,6 +82,6 @@
   std::map<std::string, base::FilePath> component_install_paths_;
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // CHROMEOS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_FAKE_IMAGE_LOADER_CLIENT_H_
diff --git a/chromeos/dbus/image_loader/image_loader_client.cc b/chromeos/ash/components/dbus/image_loader/image_loader_client.cc
similarity index 96%
rename from chromeos/dbus/image_loader/image_loader_client.cc
rename to chromeos/ash/components/dbus/image_loader/image_loader_client.cc
index 9bdbb7e9..4d860b06 100644
--- a/chromeos/dbus/image_loader/image_loader_client.cc
+++ b/chromeos/ash/components/dbus/image_loader/image_loader_client.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/image_loader/image_loader_client.h"
+#include "chromeos/ash/components/dbus/image_loader/image_loader_client.h"
 
 #include <utility>
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chromeos/dbus/image_loader/fake_image_loader_client.h"
+#include "chromeos/ash/components/dbus/image_loader/fake_image_loader_client.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
@@ -16,7 +16,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace ash {
 
 namespace {
 
@@ -198,4 +198,4 @@
   g_instance = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chromeos/dbus/image_loader/image_loader_client.h b/chromeos/ash/components/dbus/image_loader/image_loader_client.h
similarity index 89%
rename from chromeos/dbus/image_loader/image_loader_client.h
rename to chromeos/ash/components/dbus/image_loader/image_loader_client.h
index 6e043048..78737b3 100644
--- a/chromeos/dbus/image_loader/image_loader_client.h
+++ b/chromeos/ash/components/dbus/image_loader/image_loader_client.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
-#define CHROMEOS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
 
 #include <memory>
 #include <string>
@@ -14,11 +14,11 @@
 #include "chromeos/dbus/common/dbus_client.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
 
-namespace chromeos {
+namespace ash {
 
 // ImageLoaderClient is used to communicate with the ImageLoader service, which
 // registers and loads component updates on Chrome OS.
-class COMPONENT_EXPORT(CHROMEOS_DBUS_IMAGE_LOADER) ImageLoaderClient
+class COMPONENT_EXPORT(ASH_DBUS_IMAGE_LOADER) ImageLoaderClient
     : public DBusClient {
  public:
   // Returns the global instance if initialized. May return null.
@@ -74,6 +74,6 @@
   ~ImageLoaderClient() override;
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // CHROMEOS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_IMAGE_LOADER_IMAGE_LOADER_CLIENT_H_
diff --git a/chromeos/dbus/runtime_probe/BUILD.gn b/chromeos/ash/components/dbus/runtime_probe/BUILD.gn
similarity index 85%
rename from chromeos/dbus/runtime_probe/BUILD.gn
rename to chromeos/ash/components/dbus/runtime_probe/BUILD.gn
index 2c44ba9..3197072 100644
--- a/chromeos/dbus/runtime_probe/BUILD.gn
+++ b/chromeos/ash/components/dbus/runtime_probe/BUILD.gn
@@ -8,8 +8,8 @@
 assert(is_chromeos_ash, "Non-Chrome-OS builds must not depend on //chromeos")
 
 component("runtime_probe") {
-  output_name = "chromeos_runtime_probe"
-  defines = [ "IS_CHROMEOS_DBUS_RUNTIME_PROBE_IMPL" ]
+  output_name = "ash_runtime_probe"
+  defines = [ "IS_ASH_DBUS_RUNTIME_PROBE_IMPL" ]
   deps = [
     ":proto",
     "//base",
@@ -32,5 +32,5 @@
   # file, instead we specify lite runtime here.
   cc_generator_options = "lite=true:"
 
-  proto_out_dir = "chromeos/dbus/runtime_probe"
+  proto_out_dir = "chromeos/ash/components/dbus/runtime_probe"
 }
diff --git a/chromeos/dbus/runtime_probe/fake_runtime_probe_client.cc b/chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.cc
similarity index 94%
rename from chromeos/dbus/runtime_probe/fake_runtime_probe_client.cc
rename to chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.cc
index 1dd3cd41..76984f16 100644
--- a/chromeos/dbus/runtime_probe/fake_runtime_probe_client.cc
+++ b/chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/runtime_probe/fake_runtime_probe_client.h"
+#include "chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.h"
 
 #include <utility>
 
 #include "base/bind.h"
 #include "base/threading/thread_task_runner_handle.h"
 
-namespace chromeos {
+namespace ash {
 
 namespace {
 constexpr int kLiveValuesLimit = 42;
@@ -68,4 +68,4 @@
       FROM_HERE, base::BindOnce(std::move(callback), result));
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chromeos/dbus/runtime_probe/fake_runtime_probe_client.h b/chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.h
similarity index 74%
rename from chromeos/dbus/runtime_probe/fake_runtime_probe_client.h
rename to chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.h
index bc511fb..d288178 100644
--- a/chromeos/dbus/runtime_probe/fake_runtime_probe_client.h
+++ b/chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.h
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
-#define CHROMEOS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
 
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
-#include "chromeos/dbus/runtime_probe/runtime_probe_client.h"
+#include "chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h"
 
-namespace chromeos {
+namespace ash {
 
 // FakeRuntimeProbeClient is a light mock of RuntimeProbeClient used for
 // used for tests and when running ChromeOS build on Linux.
-class COMPONENT_EXPORT(CHROMEOS_DBUS_RUNTIME_PROBE) FakeRuntimeProbeClient
+class COMPONENT_EXPORT(ASH_DBUS_RUNTIME_PROBE) FakeRuntimeProbeClient
     : public RuntimeProbeClient {
  public:
   FakeRuntimeProbeClient();
@@ -39,6 +39,6 @@
   base::WeakPtrFactory<FakeRuntimeProbeClient> weak_ptr_factory_{this};
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // CHROMEOS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_FAKE_RUNTIME_PROBE_CLIENT_H_
diff --git a/chromeos/dbus/runtime_probe/runtime_probe_client.cc b/chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.cc
similarity index 94%
rename from chromeos/dbus/runtime_probe/runtime_probe_client.cc
rename to chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.cc
index f54a8276..66a747e 100644
--- a/chromeos/dbus/runtime_probe/runtime_probe_client.cc
+++ b/chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/runtime_probe/runtime_probe_client.h"
+#include "chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h"
 
 #include <string>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "chromeos/dbus/runtime_probe/fake_runtime_probe_client.h"
+#include "chromeos/ash/components/dbus/runtime_probe/fake_runtime_probe_client.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "third_party/cros_system_api/dbus/runtime_probe/dbus-constants.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 RuntimeProbeClient* g_instance = nullptr;
@@ -114,4 +114,4 @@
   g_instance = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chromeos/dbus/runtime_probe/runtime_probe_client.h b/chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h
similarity index 77%
rename from chromeos/dbus/runtime_probe/runtime_probe_client.h
rename to chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h
index c5e1a40..db2e0add 100644
--- a/chromeos/dbus/runtime_probe/runtime_probe_client.h
+++ b/chromeos/ash/components/dbus/runtime_probe/runtime_probe_client.h
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
-#define CHROMEOS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
+#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
+#define CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
 
 #include "base/component_export.h"
+#include "chromeos/ash/components/dbus/runtime_probe/runtime_probe.pb.h"
 #include "chromeos/dbus/common/dbus_client.h"
 #include "chromeos/dbus/common/dbus_method_call_status.h"
-#include "chromeos/dbus/runtime_probe/runtime_probe.pb.h"
 #include "dbus/object_proxy.h"
 
-namespace chromeos {
+namespace ash {
 
 // RuntimeProbeClient is used to communicate with Runtime Probe, which provides
 // data for hardware telemetry.
-class COMPONENT_EXPORT(CHROMEOS_DBUS_RUNTIME_PROBE) RuntimeProbeClient
+class COMPONENT_EXPORT(ASH_DBUS_RUNTIME_PROBE) RuntimeProbeClient
     : public DBusClient {
  public:
   using RuntimeProbeCallback = DBusMethodCallback<runtime_probe::ProbeResult>;
@@ -45,6 +45,6 @@
   ~RuntimeProbeClient() override;
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // CHROMEOS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
+#endif  // CHROMEOS_ASH_COMPONENTS_DBUS_RUNTIME_PROBE_RUNTIME_PROBE_CLIENT_H_
diff --git a/chromeos/ash/components/dbus/userdataauth/arc_quota_client.cc b/chromeos/ash/components/dbus/userdataauth/arc_quota_client.cc
index 5afd3869..dd0aa25 100644
--- a/chromeos/ash/components/dbus/userdataauth/arc_quota_client.cc
+++ b/chromeos/ash/components/dbus/userdataauth/arc_quota_client.cc
@@ -106,13 +106,6 @@
                     std::move(callback));
   }
 
-  void SetProjectId(const ::user_data_auth::SetProjectIdRequest& request,
-                    SetProjectIdCallback callback) override {
-    CallProtoMethod(::user_data_auth::kSetProjectId,
-                    ::user_data_auth::kArcQuotaInterface, request,
-                    std::move(callback));
-  }
-
  private:
   // Calls cryptohomed's |method_name| method in |interface_name| interface,
   // passing in |request| as input with |timeout_ms|. Once the (asynchronous)
diff --git a/chromeos/ash/components/dbus/userdataauth/arc_quota_client.h b/chromeos/ash/components/dbus/userdataauth/arc_quota_client.h
index b5a0cdf..2890998 100644
--- a/chromeos/ash/components/dbus/userdataauth/arc_quota_client.h
+++ b/chromeos/ash/components/dbus/userdataauth/arc_quota_client.h
@@ -32,8 +32,6 @@
       DBusMethodCallback<::user_data_auth::GetCurrentSpaceForArcGidReply>;
   using GetCurrentSpaceForArcProjectIdCallback =
       DBusMethodCallback<::user_data_auth::GetCurrentSpaceForArcProjectIdReply>;
-  using SetProjectIdCallback =
-      DBusMethodCallback<::user_data_auth::SetProjectIdReply>;
 
   // Not copyable or movable.
   ArcQuotaClient(const ArcQuotaClient&) = delete;
@@ -77,11 +75,6 @@
       const ::user_data_auth::GetCurrentSpaceForArcProjectIdRequest& request,
       GetCurrentSpaceForArcProjectIdCallback callback) = 0;
 
-  // Set the ARC Project ID.
-  virtual void SetProjectId(
-      const ::user_data_auth::SetProjectIdRequest& request,
-      SetProjectIdCallback callback) = 0;
-
  protected:
   // Initialize/Shutdown should be used instead.
   ArcQuotaClient();
diff --git a/chromeos/ash/components/dbus/userdataauth/arc_quota_client_unittest.cc b/chromeos/ash/components/dbus/userdataauth/arc_quota_client_unittest.cc
index 7527211..215c0455 100644
--- a/chromeos/ash/components/dbus/userdataauth/arc_quota_client_unittest.cc
+++ b/chromeos/ash/components/dbus/userdataauth/arc_quota_client_unittest.cc
@@ -106,7 +106,6 @@
       expected_get_current_space_for_arc_gid_reply_;
   ::user_data_auth::GetCurrentSpaceForArcProjectIdReply
       expected_get_current_space_for_arc_project_id_reply_;
-  ::user_data_auth::SetProjectIdReply expected_set_project_id_reply_;
 
   // When it is set `true`, an invalid array of bytes that cannot be parsed will
   // be the response.
@@ -141,8 +140,6 @@
                ::user_data_auth::kGetCurrentSpaceForArcProjectId) {
       writer.AppendProtoAsArrayOfBytes(
           expected_get_current_space_for_arc_project_id_reply_);
-    } else if (method_call->GetMember() == ::user_data_auth::kSetProjectId) {
-      writer.AppendProtoAsArrayOfBytes(expected_set_project_id_reply_);
     } else {
       ASSERT_FALSE(true) << "Unrecognized member: " << method_call->GetMember();
     }
@@ -220,16 +217,4 @@
                      expected_get_current_space_for_arc_project_id_reply_));
 }
 
-TEST_F(ArcQuotaClientTest, SetProjectId) {
-  expected_set_project_id_reply_.set_success(true);
-  absl::optional<::user_data_auth::SetProjectIdReply> result_reply;
-
-  client_->SetProjectId(::user_data_auth::SetProjectIdRequest(),
-                        CreateCopyCallback(&result_reply));
-  base::RunLoop().RunUntilIdle();
-  ASSERT_NE(result_reply, absl::nullopt);
-  EXPECT_TRUE(
-      ProtobufEquals(result_reply.value(), expected_set_project_id_reply_));
-}
-
 }  // namespace ash
diff --git a/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.cc b/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.cc
index 89124dc..527d6f9 100644
--- a/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.cc
+++ b/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.cc
@@ -51,11 +51,6 @@
     GetCurrentSpaceForArcProjectIdCallback callback) {
   // Does nothing by default.
 }
-void FakeArcQuotaClient::SetProjectId(
-    const ::user_data_auth::SetProjectIdRequest& request,
-    SetProjectIdCallback callback) {
-  // Does nothing by default.
-}
 
 void FakeArcQuotaClient::WaitForServiceToBeAvailable(
     chromeos::WaitForServiceToBeAvailableCallback callback) {
diff --git a/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.h b/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.h
index ff24140..71d7a4b 100644
--- a/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.h
+++ b/chromeos/ash/components/dbus/userdataauth/fake_arc_quota_client.h
@@ -40,8 +40,6 @@
   void GetCurrentSpaceForArcProjectId(
       const ::user_data_auth::GetCurrentSpaceForArcProjectIdRequest& request,
       GetCurrentSpaceForArcProjectIdCallback callback) override;
-  void SetProjectId(const ::user_data_auth::SetProjectIdRequest& request,
-                    SetProjectIdCallback callback) override;
 
   // WaitForServiceToBeAvailable() related:
 
diff --git a/chromeos/ash/services/assistant/BUILD.gn b/chromeos/ash/services/assistant/BUILD.gn
index cd15ffa..c7a91b1 100644
--- a/chromeos/ash/services/assistant/BUILD.gn
+++ b/chromeos/ash/services/assistant/BUILD.gn
@@ -59,13 +59,13 @@
     "//ash/constants",
     "//base",
     "//chromeos/ash/components/assistant:buildflags",
+    "//chromeos/ash/services/assistant/public/proto",
     "//chromeos/dbus",
     "//chromeos/dbus/dlcservice:dlcservice",
     "//chromeos/dbus/dlcservice:dlcservice_proto",
     "//chromeos/dbus/power",
     "//chromeos/dbus/power:power_manager_proto",
     "//chromeos/dbus/util",
-    "//chromeos/services/assistant/public/proto",
     "//chromeos/services/libassistant/public/mojom",
     "//chromeos/strings",
     "//components/account_id",
@@ -169,7 +169,7 @@
     "//chromeos/ash/components/assistant:buildflags",
     "//chromeos/ash/services/assistant/public/cpp",
     "//chromeos/ash/services/assistant/public/mojom",
-    "//chromeos/services/assistant/public/proto",
+    "//chromeos/ash/services/assistant/public/proto",
     "//chromeos/services/assistant/public/shared",
     "//chromeos/services/libassistant/public/mojom",
     "//mojo/public/cpp/bindings",
diff --git a/chromeos/ash/services/assistant/assistant_settings_impl.cc b/chromeos/ash/services/assistant/assistant_settings_impl.cc
index 3dbf9052..8a43c3dc 100644
--- a/chromeos/ash/services/assistant/assistant_settings_impl.cc
+++ b/chromeos/ash/services/assistant/assistant_settings_impl.cc
@@ -11,9 +11,9 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/ash/services/assistant/service_context.h"
 #include "chromeos/dbus/util/version_loader.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/services/libassistant/public/mojom/settings_controller.mojom.h"
 #include "chromeos/services/libassistant/public/mojom/speaker_id_enrollment_controller.mojom.h"
 
diff --git a/chromeos/ash/services/assistant/public/proto/BUILD.gn b/chromeos/ash/services/assistant/public/proto/BUILD.gn
new file mode 100644
index 0000000..b352446
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2018 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/chromeos/ui_mode.gni")
+import("//third_party/protobuf/proto_library.gni")
+
+assert(is_chromeos_ash, "Non Chrome OS builds cannot depend on //chromeos/ash")
+
+proto_library("proto") {
+  proto_in_dir = "//"
+  sources = [
+    "about_me_settings_ui.proto",
+    "activity_control_settings_common.proto",
+    "activity_control_settings_ui.proto",
+    "assistant_device_settings_ui.proto",
+    "consent_flow_ui.proto",
+    "email_opt_in_ui.proto",
+    "gaia_user_context_ui.proto",
+    "get_settings_ui.proto",
+    "header.proto",
+    "settings_ui.proto",
+  ]
+}
diff --git a/chromeos/ash/services/assistant/public/proto/about_me_settings_ui.proto b/chromeos/ash/services/assistant/public/proto/about_me_settings_ui.proto
new file mode 100644
index 0000000..daffec3
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/about_me_settings_ui.proto
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+message AboutMeSettingsUi {
+  // Nickname and its pronunciation. These fields would be empty if user has
+  // never configured a nickname before.
+  optional string name = 1;
+  // optional string name_pronunciation = 2;
+
+  // If user has never set it before, the default will be based on the locale
+  // from header. Defaults to fahrenheit for en-US, and celsius for everything
+  // else.
+  optional WeatherUnit weather_unit = 3;
+
+  // The official first and full name.
+  // optional string first_name = 6;
+  optional string full_name = 7;
+}
+
+// Only the provided fields will be updated.
+message AboutMeSettingsUiUpdate {
+  optional string name = 1;
+  optional string name_pronunciation = 2;
+  optional WeatherUnit weather_unit = 3;
+}
+
+message AboutMeSettingsUiUpdateResult {
+  // Localized message to display to the users regarding email optin status.
+  optional string email_optin_message = 2;
+}
+
+enum WeatherUnit {
+  CELSIUS = 0;
+  FAHRENHEIT = 1;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/activity_control_settings_common.proto b/chromeos/ash/services/assistant/public/proto/activity_control_settings_common.proto
new file mode 100644
index 0000000..942bd49
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/activity_control_settings_common.proto
@@ -0,0 +1,56 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// UI texts for the ClassicActivityControl UI type which follows the "classic"
+// pattern of: title, intro text, one zippy per setting with [name, short
+// summary, consent] and a shared footer. Each text is a SafeHtmlProto that can
+// contain the following HTML tags: [b, i, br, p, a, ul, li].
+message ClassicActivityControlUiTexts {
+  // UI description for the setting section shown on the consent screen.
+  // Always present.
+  message SettingZippy {
+    // Title of the zippy.
+    // Always present.
+    optional string title = 1;
+
+    // A list of paragraphs giving a high-level summary of what this
+    // setting is about.
+    // Always present.
+    repeated string description_paragraph = 2;
+
+    // A list of paragraphs providing additional information and the
+    // main consent language of the setting.
+    // Always present.
+    repeated string additional_info_paragraph = 3;
+
+    // The URI of an icon that should be displayed for the setting.
+    // Always present.
+    optional string icon_uri = 4;
+
+    // Text for button at the end of the last description paragraph that opens
+    // a learn more dialog.
+    optional string learn_more = 5;
+
+    // The setting set the text in this zippy corresponds to. This can be used
+    // by clients for ARI logging.
+    optional SettingSetId setting_set_id = 6;
+  }
+  repeated SettingZippy setting_zippy = 7;
+}
+
+enum SettingSetId {
+  UNKNOWN_SETTING_SET_ID = 0;
+
+  // Web & App Activity.
+  WAA = 5;
+
+  // Device Applications Information.
+  DA = 11;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/activity_control_settings_ui.proto b/chromeos/ash/services/assistant/public/proto/activity_control_settings_ui.proto
new file mode 100644
index 0000000..1cc93993
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/activity_control_settings_ui.proto
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+message ActivityControlSettingsUiSelector {
+  // An ID that uniquely identifies a single consent screen / client integration
+  // with consent flow.
+  // Required.
+  enum FlowId {
+    UNKNOWN = 0;
+    // FlowId for onboarding for the setup wizard on Chrome OS.
+    ASSISTANT_SUW_ONBOARDING_ON_CHROME_OS = 16;
+  }
+  optional FlowId flow_id = 1;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.proto b/chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.proto
new file mode 100644
index 0000000..edec56e
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.proto
@@ -0,0 +1,44 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+message AssistantDevice {
+  // The type of assistant device.
+  enum Type {
+    CROS = 17;
+  }
+}
+
+message AssistantDeviceSettingsUiUpdate {
+  // A list of assistant device settings update.
+  repeated AssistantDeviceSettingsUpdate assistant_device_settings_update = 1;
+}
+
+// Write only fields should go into AssistantDeviceSettingsUpdate.
+message AssistantDeviceSettingsUpdate {
+  optional string device_id = 1;
+
+  optional AssistantDevice.Type assistant_device_type = 3 [default = CROS];
+
+  optional AssistantDeviceSettings device_settings = 2;
+}
+
+message AssistantDeviceSettings {
+  // Whether this device may display/read out personal info.
+  enum PersonalReadout {
+    // This device may display/read out personal info.
+    PERSONAL_READOUT_ENABLED = 1;
+  }
+  optional PersonalReadout personal_readout = 2;
+
+  optional string locale = 5;
+
+  // Indicates whether the user has enabled speaker-id for this device.
+  optional bool speaker_id_enabled = 7;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/consent_flow_ui.proto b/chromeos/ash/services/assistant/public/proto/consent_flow_ui.proto
new file mode 100644
index 0000000..83b2df1e
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/consent_flow_ui.proto
@@ -0,0 +1,196 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// TODO(https://crbug.com/1164001): Remove 'public' notion when internal codes
+// update the path for assistant service to ch/ash/services/assistant.
+import public "chromeos/ash/services/assistant/public/proto/activity_control_settings_ui.proto";
+import public "chromeos/ash/services/assistant/public/proto/activity_control_settings_common.proto";
+
+// Parameters to ConsentFlowUi.
+message ConsentFlowUiSelector {
+  // An ID that uniquely identifies a client integration with consent flow.
+  //
+  // Required.
+  optional ActivityControlSettingsUiSelector.FlowId flow_id = 1;
+}
+
+// Represents the result of an ConsentFlow fetch. Contains a status to indicate
+// what happened, and then all the relevant pieces of data to render a UI
+// appropriate to that outcome.
+message ConsentFlowUi {
+  // A top-level indicator of what to do next in the consent flow. This
+  // field's value determines what is present in the other fields of this
+  // message.
+  enum ConsentStatus {
+    UNSPECIFIED = 0;
+
+    // Show the consent flow to the user, where they can enable any missing
+    // opt-ins.
+    ASK_FOR_CONSENT = 1;
+
+    // The user has already granted all opt-ins.
+    ALREADY_CONSENTED = 2;
+
+    // Indicates an account-level error. The client may (but is not required to)
+    // let the user retry with a different account.
+    ERROR_ACCOUNT = 3;
+
+    // Something else went wrong. Show an error message.
+    ERROR = 4;
+  }
+  optional ConsentStatus consent_status = 1;
+
+  // Representation of the consent flow UI, where the opt-ins are displayed
+  // and the user can either accept or reject to proceed.
+  //
+  // Only present if ConsentStatus is ASK_FOR_CONSENT.
+  message ConsentUi {
+    // Represents the subsection of the ConsentUi that displays and conveys user
+    // opt-ins.
+    //
+    // Only present if the user needs to opt-in.
+    message ActivityControlUi {
+      // An opaque token that the client can pass back to the server to commit
+      // a user's opt in.
+      //
+      // Required.
+      optional bytes consent_token = 2;
+
+      // An opaque token to pass to Gmscore's auditing API, which strengthens
+      // the audit trail.
+      //
+      // Required.
+      optional bytes ui_audit_key = 3;
+
+      // The title of the page.
+      //
+      // Required.
+      optional string title = 4;
+
+      // A series of paragraphs serving as the introduction to the page.
+      //
+      // Required.
+      repeated string intro_text_paragraph = 5;
+
+      // An exact copy of the user's account name, so they know exactly which
+      // account is using.
+      //
+      // Required.
+      optional string identity = 6;
+
+      // The set of settings that the user is consenting to, in the order
+      // that they should be displayed to the user.
+      //
+      // Required.
+      repeated ClassicActivityControlUiTexts.SettingZippy setting_zippy = 7;
+
+      // A series of paragraphs at the end.
+      //
+      // Required.
+      repeated string footer_paragraph = 9;
+
+      message LearnMoreDialog {
+        // Title heading of the dialog.
+        optional string title = 1;
+        message HtmlProto {
+          optional string value = 2;
+        }
+        // May contain HTML tags for like bold and hyperlinks.
+        repeated HtmlProto paragraph = 2;
+        // Bottom button that closes dialog.
+        optional string dismiss_button = 3;
+      }
+      // Learn more dialog that can be opened from the Learn More CTA within
+      // setting_zippy.
+      optional LearnMoreDialog learn_more_dialog = 13;
+    }
+    optional ActivityControlUi activity_control_ui = 1;
+
+    // Represents the subsection of the ConsentUi that displays and conveys a
+    // disclosure that the user's account might be shared with third
+    // parties the user invokes in conversation/interaction with the Assistant.
+    //
+    // Always present.
+    message ThirdPartyDisclosureUi {
+      // Title of the page.
+      //
+      // Required.
+      optional string title = 5;
+
+      // The disclosures to present.
+      //
+      // Required.
+      repeated ClassicActivityControlUiTexts.SettingZippy disclosures = 2;
+
+      // Text for button that lets user acknowledge disclosures and continue
+      // to next screen.
+      //
+      // Required.
+      optional string button_continue = 3;
+    }
+    optional ThirdPartyDisclosureUi third_party_disclosure_ui = 3;
+
+    // Contains an HTML string with links to Google's Terms of Service and
+    // Privacy Policy.
+    optional string tos_pp_links = 9;
+
+    // Text for the button that lets the user accept the opt-ins, committing
+    // their new state.
+    //
+    // Required, since the user must be able to continue past this screen.
+    optional string accept_button_text = 4;
+
+    // Text for the button that lets the user reject the opt-ins.
+    //
+    // Optional. If absent, do not let the user reject.
+    optional string reject_button_text = 5;
+  }
+  optional ConsentUi consent_ui = 2;
+
+  // One or multiple consent UIs required for rendering. This serves as a
+  // replacement for the non-repeated field. If present, prefer to use this over
+  // consent_ui, otherwise fallback to using consent_ui. In the case that
+  // neither exists, the user does not need to (or cannot) perform any UDC
+  // consents. It is REQUIRED to present the consents in the order provided in
+  // this field.
+  repeated ConsentUi multi_consent_ui = 8;
+}
+
+// Represents an update to consent flow opt-ins. This occurs when the user
+// clicks a button to opt-in.
+message ConsentFlowUiUpdate {
+  // An ID that uniquely identifies a single consent screen / client integration
+  // with consent flow.
+  //
+  // Required.
+  optional ActivityControlSettingsUiSelector.FlowId flow_id = 4;
+
+  // If present, opt the user in.
+  optional bytes consent_token = 1;
+
+  // True means the user saw 3p disclosure and acknowledged it, false means 3p
+  // disclosure was not presented to the user.
+  optional bool saw_third_party_disclosure = 3;
+}
+
+// Represents the response to updating consent flow.
+message ConsentFlowUiUpdateResult {
+  // Represents the outcome of the update; did it succeed or fail?
+  enum UpdateStatus {
+    UNSPECIFIED = 0;
+
+    // The update was successfully executed. The user can proceed.
+    SUCCESS = 1;
+
+    // The update was not successfully executed. The user should not proceed.
+    ERROR = 2;
+  }
+  optional UpdateStatus update_status = 1;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/email_opt_in_ui.proto b/chromeos/ash/services/assistant/public/proto/email_opt_in_ui.proto
new file mode 100644
index 0000000..26084a9
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/email_opt_in_ui.proto
@@ -0,0 +1,69 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is govered by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// Represents the subsection of the ConsentUi that displays and conveys an
+// opt-in to receive email update abouts the Assistant.
+message EmailOptInUi {
+  // Title text to show on the email opt-in.
+  optional string title = 2;
+
+  // A paragraph telling the user what they get from email updates.
+  optional string description = 3;
+
+  // Supplementary text that is only required in some locales which tells
+  // users how to opt out.
+  optional string legal_text = 4;
+
+  // Whether the switch should default to enabled. This affects the opt-in
+  // state if the user does not override it.
+  optional bool default_enabled = 5;
+
+  // URI of a icon to display alongside the email section.
+  optional string icon_uri = 6;
+
+  // Text for the button that lets the user accept the opt-ins, committing
+  // their new state.
+  //
+  // Required, since the user must be able to continue past this screen.
+  optional string accept_button_text = 7;
+}
+
+message EmailOptInUpdate {
+  // Represents an update to the user's email notification preference.
+  enum EmailOptInUpdateState {
+    UNSPECIFIED = 0;
+
+    // The user wants to receive email notifications about the Assistant.
+    OPT_IN = 2;
+
+    // The user does not want to receive email notifications about the
+    // Assistant.
+    OPT_OUT = 3;
+  }
+
+  optional EmailOptInUpdateState email_opt_in_update_state = 1;
+}
+
+// Represents the response to updating email opt-in.
+message EmailOptInUpdateResult {
+  // Represents the outcome of the update; did it succeed or fail?
+  enum UpdateStatus {
+    UNSPECIFIED = 0;
+
+    // The update was successfully executed.
+    SUCCESS = 1;
+
+    // The update was not successfully executed.
+    ERROR = 2;
+  }
+
+  optional UpdateStatus update_status = 1;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/gaia_user_context_ui.proto b/chromeos/ash/services/assistant/public/proto/gaia_user_context_ui.proto
new file mode 100644
index 0000000..00658dc
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/gaia_user_context_ui.proto
@@ -0,0 +1,32 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// Parameters about the GAIA user's context.
+// It only applies to the primary user under the multi-user scenario.
+message GaiaUserContextUi {
+  // Whether the query comes from a GAIA user.
+  optional bool is_gaia_user = 1;
+
+  // Whether Web & App Activity is enabled.
+  // This bit only makes sense for GAIA traffic.
+  optional bool waa_enabled = 2;
+
+  // Whether Web & App Activity is disabled by Dasher domain admin.
+  // This bit only makes sense for GAIA traffic.
+  optional bool waa_disabled_by_dasher_domain = 3;
+
+  // Whether Assistant is disabled by Dasher domain admin.
+  // This bit only makes sense for GAIA traffic.
+  optional bool assistant_disabled_by_dasher_domain = 4;
+
+  // Whether Device Apps is enabled to store user's apps which could help
+  // improve user experience across Google services.
+  optional bool device_apps_enabled = 6;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/get_settings_ui.proto b/chromeos/ash/services/assistant/public/proto/get_settings_ui.proto
new file mode 100644
index 0000000..0b90df8c
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/get_settings_ui.proto
@@ -0,0 +1,27 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// TODO(https://crbug.com/1164001): Remove 'public' notion when internal codes
+// update the path for assistant service to ch/ash/services/assistant.
+import public "chromeos/ash/services/assistant/public/proto/header.proto";
+import public "chromeos/ash/services/assistant/public/proto/settings_ui.proto";
+
+// GetSettingsUi.
+message GetSettingsUiRequest {
+  // Indicates which fields in SettingsUi to fetch.
+  // Required.
+  optional SettingsUiSelector selector = 4;
+}
+
+message GetSettingsUiResponse {
+  optional SettingsUi settings = 1;
+
+  optional SettingsResponseHeader header = 2;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/header.proto b/chromeos/ash/services/assistant/public/proto/header.proto
new file mode 100644
index 0000000..0996b1d
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/header.proto
@@ -0,0 +1,21 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// Metadata for the response back to the user.
+message SettingsResponseHeader {
+  enum AcceptRejectLayout {
+    // Unspecified layout for buttons.
+    UNSPECIFIED = 0;
+    // Accept is filled on RHS, Reject is filled on LHS.
+    EQUAL_WEIGHT = 1;
+  }
+  // Controls the way the accept and reject buttons are rendered.
+  optional AcceptRejectLayout footer_button_layout = 2;
+}
diff --git a/chromeos/ash/services/assistant/public/proto/settings_ui.proto b/chromeos/ash/services/assistant/public/proto/settings_ui.proto
new file mode 100644
index 0000000..bdf2524
--- /dev/null
+++ b/chromeos/ash/services/assistant/public/proto/settings_ui.proto
@@ -0,0 +1,45 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package chromeos.assistant;
+
+// TODO(https://crbug.com/1164001): Remove 'public' notion when internal codes
+// update the path for assistant service to ch/ash/services/assistant.
+import public "chromeos/ash/services/assistant/public/proto/about_me_settings_ui.proto";
+import public "chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.proto";
+import public "chromeos/ash/services/assistant/public/proto/consent_flow_ui.proto";
+import public "chromeos/ash/services/assistant/public/proto/email_opt_in_ui.proto";
+import public "chromeos/ash/services/assistant/public/proto/gaia_user_context_ui.proto";
+
+message SettingsUi {
+  optional AboutMeSettingsUi about_me_settings = 5;
+  optional ConsentFlowUi consent_flow_ui = 27;
+  optional EmailOptInUi email_opt_in_ui = 33;
+  optional GaiaUserContextUi gaia_user_context_ui = 43;
+}
+
+message SettingsUiUpdate {
+  optional AboutMeSettingsUiUpdate about_me_settings_update = 4;
+  optional AssistantDeviceSettingsUiUpdate assistant_device_settings_update = 6;
+  optional ConsentFlowUiUpdate consent_flow_ui_update = 21;
+  optional EmailOptInUpdate email_opt_in_update = 26;
+}
+
+message SettingsUiUpdateResult {
+  optional AboutMeSettingsUiUpdateResult about_me_settings_update_result = 4;
+  optional ConsentFlowUiUpdateResult consent_flow_update_result = 11;
+  optional EmailOptInUpdateResult email_opt_in_update_result = 15;
+}
+
+// Determines which settings sub-pages should be requested to the server.
+message SettingsUiSelector {
+  optional bool about_me_settings = 5;
+  optional ConsentFlowUiSelector consent_flow_ui_selector = 35;
+  optional bool email_opt_in = 43;
+  optional bool gaia_user_context_ui = 54;
+}
diff --git a/chromeos/ash/services/assistant/test_support/fake_assistant_settings_impl.cc b/chromeos/ash/services/assistant/test_support/fake_assistant_settings_impl.cc
index 0a91e85..393f88e 100644
--- a/chromeos/ash/services/assistant/test_support/fake_assistant_settings_impl.cc
+++ b/chromeos/ash/services/assistant/test_support/fake_assistant_settings_impl.cc
@@ -7,8 +7,8 @@
 #include <utility>
 
 #include "base/callback.h"
-#include "chromeos/services/assistant/public/proto/get_settings_ui.pb.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/get_settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 
 namespace chromeos {
 namespace assistant {
diff --git a/chromeos/crosapi/mojom/web_app_service.mojom b/chromeos/crosapi/mojom/web_app_service.mojom
index 535fe0f..2348254 100644
--- a/chromeos/crosapi/mojom/web_app_service.mojom
+++ b/chromeos/crosapi/mojom/web_app_service.mojom
@@ -16,10 +16,21 @@
   string sha256_fingerprint@1;
 };
 
+// Contains the web app information used to mint an Android WebApk.
+[Stable]
+struct WebApkCreationParams {
+  // The URL of the Web App Manifest.
+  string manifest_url@0;
+
+  // A serialized webapk::WebAppManifest proto containing the information
+  // required for an Android WebApk to be minted.
+  array<uint8> webapk_manifest_proto_bytes@1;
+};
+
 // Implemented in lacros-chrome. Allows ash-chrome to modify web app state in
 // lacros-chrome.
-// Next version: 1
-// Next method id: 2
+// Next version: 2
+// Next method id: 3
 [Stable, Uuid="84eb46eb-76fe-439c-9fcb-3388492e141d"]
 interface WebAppProviderBridge {
   // Called when a web app described by |info| is installed in ARC (Android
@@ -35,6 +46,12 @@
   // See |web_app::WebAppInstallFinalizer::UninstallExternalWebApp|.
   WebAppUninstalledInArc@1(string app_id)
     => (WebAppUninstallResultCode uninstall_result);
+
+  // Called when a web app defining a share target has been installed in Lacros.
+  // Returns the information required for an Android WebApk to be minted.
+  [MinVersion=1]
+  GetWebApkCreationParams@2(string app_id)
+    => (WebApkCreationParams webapk_creation_params);
 };
 
 // An interface implemented in ash-chrome. Allows lacros-chrome:
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn
index 19839ab..fdbc0c1 100644
--- a/chromeos/dbus/BUILD.gn
+++ b/chromeos/dbus/BUILD.gn
@@ -34,9 +34,6 @@
     "//chromeos/dbus/fwupd",
     "//chromeos/dbus/gnubby",
     "//chromeos/dbus/image_burner",
-    "//chromeos/dbus/image_loader",
-    "//chromeos/dbus/runtime_probe",
-    "//chromeos/dbus/runtime_probe:proto",
     "//chromeos/dbus/util",
     "//components/account_id",
     "//components/device_event_log",
diff --git a/chromeos/dbus/missive/BUILD.gn b/chromeos/dbus/missive/BUILD.gn
index 4a35de8..32a2801d 100644
--- a/chromeos/dbus/missive/BUILD.gn
+++ b/chromeos/dbus/missive/BUILD.gn
@@ -26,3 +26,20 @@
     "missive_client.h",
   ]
 }
+
+static_library("test_support") {
+  testonly = true
+
+  sources = [
+    "missive_client_test_observer.cc",
+    "missive_client_test_observer.h",
+  ]
+
+  deps = [
+    ":missive",
+    "//base",
+    "//base/test:test_support",
+    "//components/reporting/proto:record_constants",
+    "//components/reporting/proto:record_proto",
+  ]
+}
diff --git a/chromeos/dbus/missive/missive_client_test_observer.cc b/chromeos/dbus/missive/missive_client_test_observer.cc
new file mode 100644
index 0000000..67affffc
--- /dev/null
+++ b/chromeos/dbus/missive/missive_client_test_observer.cc
@@ -0,0 +1,51 @@
+// 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 "chromeos/dbus/missive/missive_client_test_observer.h"
+
+#include <tuple>
+
+#include "base/check.h"
+#include "base/test/repeating_test_future.h"
+#include "chromeos/dbus/missive/missive_client.h"
+#include "components/reporting/proto/synced/record.pb.h"
+#include "components/reporting/proto/synced/record_constants.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace chromeos {
+
+MissiveClientTestObserver::MissiveClientTestObserver(
+    absl::optional<::reporting::Destination> destination)
+    : destination_(destination) {
+  DCHECK(MissiveClient::Get());
+  DCHECK(MissiveClient::Get()->GetTestInterface());
+
+  MissiveClient::Get()->GetTestInterface()->AddObserver(this);
+}
+
+MissiveClientTestObserver::~MissiveClientTestObserver() {
+  MissiveClient::Get()->GetTestInterface()->RemoveObserver(this);
+}
+
+void MissiveClientTestObserver::OnRecordEnqueued(
+    ::reporting::Priority priority,
+    const ::reporting::Record& record) {
+  if (destination_.has_value() &&
+      record.destination() != destination_.value()) {
+    return;
+  }
+
+  enqueued_records_.AddValue(priority, record);
+}
+
+std::tuple<::reporting::Priority, ::reporting::Record>
+MissiveClientTestObserver::GetNextEnqueuedRecord() {
+  return enqueued_records_.Take();
+}
+
+bool MissiveClientTestObserver::HasNewEnqueuedRecords() {
+  return !enqueued_records_.IsEmpty();
+}
+
+}  // namespace chromeos
diff --git a/chromeos/dbus/missive/missive_client_test_observer.h b/chromeos/dbus/missive/missive_client_test_observer.h
new file mode 100644
index 0000000..14824a10
--- /dev/null
+++ b/chromeos/dbus/missive/missive_client_test_observer.h
@@ -0,0 +1,55 @@
+// 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 CHROMEOS_DBUS_MISSIVE_MISSIVE_CLIENT_TEST_OBSERVER_H_
+#define CHROMEOS_DBUS_MISSIVE_MISSIVE_CLIENT_TEST_OBSERVER_H_
+
+#include <tuple>
+
+#include "base/test/repeating_test_future.h"
+#include "chromeos/dbus/missive/missive_client.h"
+#include "components/reporting/proto/synced/record.pb.h"
+#include "components/reporting/proto/synced/record_constants.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace chromeos {
+
+// Test helper class that observe |FakeMissiveClient| events.
+class MissiveClientTestObserver
+    : public MissiveClient::TestInterface::Observer {
+ public:
+  // If |destination| is specified, the observer will capture only enqueued
+  // records with the specified |destination|, otherwise, all records will be
+  // captured.
+  explicit MissiveClientTestObserver(
+      absl::optional<::reporting::Destination> destination = absl::nullopt);
+
+  MissiveClientTestObserver(const MissiveClientTestObserver&) = delete;
+  MissiveClientTestObserver operator=(const MissiveClientTestObserver&) =
+      delete;
+
+  ~MissiveClientTestObserver() override;
+
+  void OnRecordEnqueued(::reporting::Priority priority,
+                        const ::reporting::Record& record) override;
+
+  // Wait for next |::reporting::Record| to be enqueued and return it along with
+  // the corresponding |::reporting::Priority|.
+  std::tuple<::reporting::Priority, ::reporting::Record>
+  GetNextEnqueuedRecord();
+
+  // Return true if there is no new enqueued records that was not consumed by
+  // |GetNextEnqueuedRecord()|.
+  bool HasNewEnqueuedRecords();
+
+ private:
+  base::test::RepeatingTestFuture<::reporting::Priority, ::reporting::Record>
+      enqueued_records_;
+
+  const absl::optional<::reporting::Destination> destination_;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_DBUS_MISSIVE_MISSIVE_CLIENT_TEST_OBSERVER_H_
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index d1395d5..774e7917 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-105-5140.0-1656929358-benchmark-105.0.5161.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-105-5140.0-1656929358-benchmark-105.0.5165.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index fb43ec9c..ec112b50 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-105-5112.23-1656928499-benchmark-105.0.5161.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-105-5112.23-1656928499-benchmark-105.0.5165.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/assistant/public/proto/BUILD.gn b/chromeos/services/assistant/public/proto/BUILD.gn
index ca25ea7..9c616e26 100644
--- a/chromeos/services/assistant/public/proto/BUILD.gn
+++ b/chromeos/services/assistant/public/proto/BUILD.gn
@@ -2,9 +2,17 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# TODO(https://crbug.com/1164001): Before editing this file, please consider
+# to use chromeos/ash/services/assistant/public/cpp/BUILD.gn instead.
+# This is temporary during the migartion of assistant directories to ash.
+# We keep it until internal assistant codes are changed to use the new path
+# chromeos/ash/services/assistant.
+
 import("//third_party/protobuf/proto_library.gni")
 
 proto_library("proto") {
+  visibility = [ "//chromeos/assistant/internal/*" ]
+  proto_in_dir = "//"
   sources = [
     "about_me_settings_ui.proto",
     "activity_control_settings_common.proto",
@@ -17,4 +25,5 @@
     "header.proto",
     "settings_ui.proto",
   ]
+  deps = [ "//chromeos/ash/services/assistant/public/proto" ]
 }
diff --git a/chromeos/services/assistant/public/proto/about_me_settings_ui.proto b/chromeos/services/assistant/public/proto/about_me_settings_ui.proto
index daffec3..42db7d00 100644
--- a/chromeos/services/assistant/public/proto/about_me_settings_ui.proto
+++ b/chromeos/services/assistant/public/proto/about_me_settings_ui.proto
@@ -2,41 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-message AboutMeSettingsUi {
-  // Nickname and its pronunciation. These fields would be empty if user has
-  // never configured a nickname before.
-  optional string name = 1;
-  // optional string name_pronunciation = 2;
-
-  // If user has never set it before, the default will be based on the locale
-  // from header. Defaults to fahrenheit for en-US, and celsius for everything
-  // else.
-  optional WeatherUnit weather_unit = 3;
-
-  // The official first and full name.
-  // optional string first_name = 6;
-  optional string full_name = 7;
-}
-
-// Only the provided fields will be updated.
-message AboutMeSettingsUiUpdate {
-  optional string name = 1;
-  optional string name_pronunciation = 2;
-  optional WeatherUnit weather_unit = 3;
-}
-
-message AboutMeSettingsUiUpdateResult {
-  // Localized message to display to the users regarding email optin status.
-  optional string email_optin_message = 2;
-}
-
-enum WeatherUnit {
-  CELSIUS = 0;
-  FAHRENHEIT = 1;
-}
+import public "chromeos/ash/services/assistant/public/proto/about_me_settings_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/activity_control_settings_common.proto b/chromeos/services/assistant/public/proto/activity_control_settings_common.proto
index 942bd49..897ebffa 100644
--- a/chromeos/services/assistant/public/proto/activity_control_settings_common.proto
+++ b/chromeos/services/assistant/public/proto/activity_control_settings_common.proto
@@ -2,55 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-// UI texts for the ClassicActivityControl UI type which follows the "classic"
-// pattern of: title, intro text, one zippy per setting with [name, short
-// summary, consent] and a shared footer. Each text is a SafeHtmlProto that can
-// contain the following HTML tags: [b, i, br, p, a, ul, li].
-message ClassicActivityControlUiTexts {
-  // UI description for the setting section shown on the consent screen.
-  // Always present.
-  message SettingZippy {
-    // Title of the zippy.
-    // Always present.
-    optional string title = 1;
-
-    // A list of paragraphs giving a high-level summary of what this
-    // setting is about.
-    // Always present.
-    repeated string description_paragraph = 2;
-
-    // A list of paragraphs providing additional information and the
-    // main consent language of the setting.
-    // Always present.
-    repeated string additional_info_paragraph = 3;
-
-    // The URI of an icon that should be displayed for the setting.
-    // Always present.
-    optional string icon_uri = 4;
-
-    // Text for button at the end of the last description paragraph that opens
-    // a learn more dialog.
-    optional string learn_more = 5;
-
-    // The setting set the text in this zippy corresponds to. This can be used
-    // by clients for ARI logging.
-    optional SettingSetId setting_set_id = 6;
-  }
-  repeated SettingZippy setting_zippy = 7;
-}
-
-enum SettingSetId {
-  UNKNOWN_SETTING_SET_ID = 0;
-
-  // Web & App Activity.
-  WAA = 5;
-
-  // Device Applications Information.
-  DA = 11;
-}
+import public "chromeos/ash/services/assistant/public/proto/activity_control_settings_common.proto";
diff --git a/chromeos/services/assistant/public/proto/activity_control_settings_ui.proto b/chromeos/services/assistant/public/proto/activity_control_settings_ui.proto
index 1cc93993..dc95529 100644
--- a/chromeos/services/assistant/public/proto/activity_control_settings_ui.proto
+++ b/chromeos/services/assistant/public/proto/activity_control_settings_ui.proto
@@ -2,20 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-message ActivityControlSettingsUiSelector {
-  // An ID that uniquely identifies a single consent screen / client integration
-  // with consent flow.
-  // Required.
-  enum FlowId {
-    UNKNOWN = 0;
-    // FlowId for onboarding for the setup wizard on Chrome OS.
-    ASSISTANT_SUW_ONBOARDING_ON_CHROME_OS = 16;
-  }
-  optional FlowId flow_id = 1;
-}
+import public "chromeos/ash/services/assistant/public/proto/activity_control_settings_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/assistant_device_settings_ui.proto b/chromeos/services/assistant/public/proto/assistant_device_settings_ui.proto
index 6891ab59..957cd84d 100644
--- a/chromeos/services/assistant/public/proto/assistant_device_settings_ui.proto
+++ b/chromeos/services/assistant/public/proto/assistant_device_settings_ui.proto
@@ -2,41 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-message AssistantDevice {
-  // The type of assistant device.
-  enum Type { CROS = 17; }
-}
-
-message AssistantDeviceSettingsUiUpdate {
-  // A list of assistant device settings update.
-  repeated AssistantDeviceSettingsUpdate assistant_device_settings_update = 1;
-}
-
-// Write only fields should go into AssistantDeviceSettingsUpdate.
-message AssistantDeviceSettingsUpdate {
-  optional string device_id = 1;
-
-  optional AssistantDevice.Type assistant_device_type = 3 [default = CROS];
-
-  optional AssistantDeviceSettings device_settings = 2;
-}
-
-message AssistantDeviceSettings {
-  // Whether this device may display/read out personal info.
-  enum PersonalReadout {
-    // This device may display/read out personal info.
-    PERSONAL_READOUT_ENABLED = 1;
-  }
-  optional PersonalReadout personal_readout = 2;
-
-  optional string locale = 5;
-
-  // Indicates whether the user has enabled speaker-id for this device.
-  optional bool speaker_id_enabled = 7;
-}
+import public "chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/consent_flow_ui.proto b/chromeos/services/assistant/public/proto/consent_flow_ui.proto
index 71f72087..b2e3651 100644
--- a/chromeos/services/assistant/public/proto/consent_flow_ui.proto
+++ b/chromeos/services/assistant/public/proto/consent_flow_ui.proto
@@ -2,191 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-import "activity_control_settings_ui.proto";
-import "activity_control_settings_common.proto";
-
-// Parameters to ConsentFlowUi.
-message ConsentFlowUiSelector {
-  // An ID that uniquely identifies a client integration with consent flow.
-  //
-  // Required.
-  optional ActivityControlSettingsUiSelector.FlowId flow_id = 1;
-}
-
-// Represents the result of an ConsentFlow fetch. Contains a status to indicate
-// what happened, and then all the relevant pieces of data to render a UI
-// appropriate to that outcome.
-message ConsentFlowUi {
-  // A top-level indicator of what to do next in the consent flow. This
-  // field's value determines what is present in the other fields of this
-  // message.
-  enum ConsentStatus {
-    UNSPECIFIED = 0;
-
-    // Show the consent flow to the user, where they can enable any missing
-    // opt-ins.
-    ASK_FOR_CONSENT = 1;
-
-    // The user has already granted all opt-ins.
-    ALREADY_CONSENTED = 2;
-
-    // Indicates an account-level error. The client may (but is not required to)
-    // let the user retry with a different account.
-    ERROR_ACCOUNT = 3;
-
-    // Something else went wrong. Show an error message.
-    ERROR = 4;
-  }
-  optional ConsentStatus consent_status = 1;
-
-  // Representation of the consent flow UI, where the opt-ins are displayed
-  // and the user can either accept or reject to proceed.
-  //
-  // Only present if ConsentStatus is ASK_FOR_CONSENT.
-  message ConsentUi {
-    // Represents the subsection of the ConsentUi that displays and conveys user
-    // opt-ins.
-    //
-    // Only present if the user needs to opt-in.
-    message ActivityControlUi {
-      // An opaque token that the client can pass back to the server to commit
-      // a user's opt in.
-      //
-      // Required.
-      optional bytes consent_token = 2;
-
-      // An opaque token to pass to Gmscore's auditing API, which strengthens
-      // the audit trail.
-      //
-      // Required.
-      optional bytes ui_audit_key = 3;
-
-      // The title of the page.
-      //
-      // Required.
-      optional string title = 4;
-
-      // A series of paragraphs serving as the introduction to the page.
-      //
-      // Required.
-      repeated string intro_text_paragraph = 5;
-
-      // An exact copy of the user's account name, so they know exactly which
-      // account is using.
-      //
-      // Required.
-      optional string identity = 6;
-
-      // The set of settings that the user is consenting to, in the order
-      // that they should be displayed to the user.
-      //
-      // Required.
-      repeated ClassicActivityControlUiTexts.SettingZippy setting_zippy = 7;
-
-      // A series of paragraphs at the end.
-      //
-      // Required.
-      repeated string footer_paragraph = 9;
-
-      message LearnMoreDialog {
-        // Title heading of the dialog.
-        optional string title = 1;
-        message HtmlProto { optional string value = 2; }
-        // May contain HTML tags for like bold and hyperlinks.
-        repeated HtmlProto paragraph = 2;
-        // Bottom button that closes dialog.
-        optional string dismiss_button = 3;
-      }
-      // Learn more dialog that can be opened from the Learn More CTA within
-      // setting_zippy.
-      optional LearnMoreDialog learn_more_dialog = 13;
-    }
-    optional ActivityControlUi activity_control_ui = 1;
-
-    // Represents the subsection of the ConsentUi that displays and conveys a
-    // disclosure that the user's account might be shared with third
-    // parties the user invokes in conversation/interaction with the Assistant.
-    //
-    // Always present.
-    message ThirdPartyDisclosureUi {
-      // Title of the page.
-      //
-      // Required.
-      optional string title = 5;
-
-      // The disclosures to present.
-      //
-      // Required.
-      repeated ClassicActivityControlUiTexts.SettingZippy disclosures = 2;
-
-      // Text for button that lets user acknowledge disclosures and continue
-      // to next screen.
-      //
-      // Required.
-      optional string button_continue = 3;
-    }
-    optional ThirdPartyDisclosureUi third_party_disclosure_ui = 3;
-
-    // Contains an HTML string with links to Google's Terms of Service and
-    // Privacy Policy.
-    optional string tos_pp_links = 9;
-
-    // Text for the button that lets the user accept the opt-ins, committing
-    // their new state.
-    //
-    // Required, since the user must be able to continue past this screen.
-    optional string accept_button_text = 4;
-
-    // Text for the button that lets the user reject the opt-ins.
-    //
-    // Optional. If absent, do not let the user reject.
-    optional string reject_button_text = 5;
-  }
-  optional ConsentUi consent_ui = 2;
-
-  // One or multiple consent UIs required for rendering. This serves as a
-  // replacement for the non-repeated field. If present, prefer to use this over
-  // consent_ui, otherwise fallback to using consent_ui. In the case that
-  // neither exists, the user does not need to (or cannot) perform any UDC
-  // consents. It is REQUIRED to present the consents in the order provided in
-  // this field.
-  repeated ConsentUi multi_consent_ui = 8;
-}
-
-// Represents an update to consent flow opt-ins. This occurs when the user
-// clicks a button to opt-in.
-message ConsentFlowUiUpdate {
-  // An ID that uniquely identifies a single consent screen / client integration
-  // with consent flow.
-  //
-  // Required.
-  optional ActivityControlSettingsUiSelector.FlowId flow_id = 4;
-
-  // If present, opt the user in.
-  optional bytes consent_token = 1;
-
-  // True means the user saw 3p disclosure and acknowledged it, false means 3p
-  // disclosure was not presented to the user.
-  optional bool saw_third_party_disclosure = 3;
-}
-
-// Represents the response to updating consent flow.
-message ConsentFlowUiUpdateResult {
-  // Represents the outcome of the update; did it succeed or fail?
-  enum UpdateStatus {
-    UNSPECIFIED = 0;
-
-    // The update was successfully executed. The user can proceed.
-    SUCCESS = 1;
-
-    // The update was not successfully executed. The user should not proceed.
-    ERROR = 2;
-  }
-  optional UpdateStatus update_status = 1;
-}
+import public "chromeos/ash/services/assistant/public/proto/consent_flow_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/email_opt_in_ui.proto b/chromeos/services/assistant/public/proto/email_opt_in_ui.proto
index 26084a9..7d43c39 100644
--- a/chromeos/services/assistant/public/proto/email_opt_in_ui.proto
+++ b/chromeos/services/assistant/public/proto/email_opt_in_ui.proto
@@ -3,67 +3,13 @@
 // license that can be found in the LICENSE file or at
 // https://developers.google.com/open-source/licenses/bsd
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-// Represents the subsection of the ConsentUi that displays and conveys an
-// opt-in to receive email update abouts the Assistant.
-message EmailOptInUi {
-  // Title text to show on the email opt-in.
-  optional string title = 2;
-
-  // A paragraph telling the user what they get from email updates.
-  optional string description = 3;
-
-  // Supplementary text that is only required in some locales which tells
-  // users how to opt out.
-  optional string legal_text = 4;
-
-  // Whether the switch should default to enabled. This affects the opt-in
-  // state if the user does not override it.
-  optional bool default_enabled = 5;
-
-  // URI of a icon to display alongside the email section.
-  optional string icon_uri = 6;
-
-  // Text for the button that lets the user accept the opt-ins, committing
-  // their new state.
-  //
-  // Required, since the user must be able to continue past this screen.
-  optional string accept_button_text = 7;
-}
-
-message EmailOptInUpdate {
-  // Represents an update to the user's email notification preference.
-  enum EmailOptInUpdateState {
-    UNSPECIFIED = 0;
-
-    // The user wants to receive email notifications about the Assistant.
-    OPT_IN = 2;
-
-    // The user does not want to receive email notifications about the
-    // Assistant.
-    OPT_OUT = 3;
-  }
-
-  optional EmailOptInUpdateState email_opt_in_update_state = 1;
-}
-
-// Represents the response to updating email opt-in.
-message EmailOptInUpdateResult {
-  // Represents the outcome of the update; did it succeed or fail?
-  enum UpdateStatus {
-    UNSPECIFIED = 0;
-
-    // The update was successfully executed.
-    SUCCESS = 1;
-
-    // The update was not successfully executed.
-    ERROR = 2;
-  }
-
-  optional UpdateStatus update_status = 1;
-}
+import public "chromeos/ash/services/assistant/public/proto/email_opt_in_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/gaia_user_context_ui.proto b/chromeos/services/assistant/public/proto/gaia_user_context_ui.proto
index 00658dc..4721207 100644
--- a/chromeos/services/assistant/public/proto/gaia_user_context_ui.proto
+++ b/chromeos/services/assistant/public/proto/gaia_user_context_ui.proto
@@ -2,31 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-// Parameters about the GAIA user's context.
-// It only applies to the primary user under the multi-user scenario.
-message GaiaUserContextUi {
-  // Whether the query comes from a GAIA user.
-  optional bool is_gaia_user = 1;
-
-  // Whether Web & App Activity is enabled.
-  // This bit only makes sense for GAIA traffic.
-  optional bool waa_enabled = 2;
-
-  // Whether Web & App Activity is disabled by Dasher domain admin.
-  // This bit only makes sense for GAIA traffic.
-  optional bool waa_disabled_by_dasher_domain = 3;
-
-  // Whether Assistant is disabled by Dasher domain admin.
-  // This bit only makes sense for GAIA traffic.
-  optional bool assistant_disabled_by_dasher_domain = 4;
-
-  // Whether Device Apps is enabled to store user's apps which could help
-  // improve user experience across Google services.
-  optional bool device_apps_enabled = 6;
-}
+import public "chromeos/ash/services/assistant/public/proto/gaia_user_context_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/get_settings_ui.proto b/chromeos/services/assistant/public/proto/get_settings_ui.proto
index 156dacf..8d88cd00 100644
--- a/chromeos/services/assistant/public/proto/get_settings_ui.proto
+++ b/chromeos/services/assistant/public/proto/get_settings_ui.proto
@@ -2,24 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-import "header.proto";
-import "settings_ui.proto";
-
-// GetSettingsUi.
-message GetSettingsUiRequest {
-  // Indicates which fields in SettingsUi to fetch.
-  // Required.
-  optional SettingsUiSelector selector = 4;
-}
-
-message GetSettingsUiResponse {
-  optional SettingsUi settings = 1;
-
-  optional SettingsResponseHeader header = 2;
-}
+import public "chromeos/ash/services/assistant/public/proto/get_settings_ui.proto";
diff --git a/chromeos/services/assistant/public/proto/header.proto b/chromeos/services/assistant/public/proto/header.proto
index 0996b1d..fffdb3f 100644
--- a/chromeos/services/assistant/public/proto/header.proto
+++ b/chromeos/services/assistant/public/proto/header.proto
@@ -2,20 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-// Metadata for the response back to the user.
-message SettingsResponseHeader {
-  enum AcceptRejectLayout {
-    // Unspecified layout for buttons.
-    UNSPECIFIED = 0;
-    // Accept is filled on RHS, Reject is filled on LHS.
-    EQUAL_WEIGHT = 1;
-  }
-  // Controls the way the accept and reject buttons are rendered.
-  optional AcceptRejectLayout footer_button_layout = 2;
-}
+import public "chromeos/ash/services/assistant/public/proto/header.proto";
diff --git a/chromeos/services/assistant/public/proto/settings_ui.proto b/chromeos/services/assistant/public/proto/settings_ui.proto
index 8cbbcc7..cdf3d19b 100644
--- a/chromeos/services/assistant/public/proto/settings_ui.proto
+++ b/chromeos/services/assistant/public/proto/settings_ui.proto
@@ -2,42 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(https://crbug.com/1164001): Remove this file when internal assistant
+// codes are changed to use the new path chromeos/ash/services/assistant.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
 package chromeos.assistant;
 
-import "about_me_settings_ui.proto";
-import "assistant_device_settings_ui.proto";
-import "consent_flow_ui.proto";
-import "email_opt_in_ui.proto";
-import "gaia_user_context_ui.proto";
-
-message SettingsUi {
-  optional AboutMeSettingsUi about_me_settings = 5;
-  optional ConsentFlowUi consent_flow_ui = 27;
-  optional EmailOptInUi email_opt_in_ui = 33;
-  optional GaiaUserContextUi gaia_user_context_ui = 43;
-}
-
-message SettingsUiUpdate {
-  optional AboutMeSettingsUiUpdate about_me_settings_update = 4;
-  optional AssistantDeviceSettingsUiUpdate assistant_device_settings_update = 6;
-  optional ConsentFlowUiUpdate consent_flow_ui_update = 21;
-  optional EmailOptInUpdate email_opt_in_update = 26;
-}
-
-message SettingsUiUpdateResult {
-  optional AboutMeSettingsUiUpdateResult about_me_settings_update_result = 4;
-  optional ConsentFlowUiUpdateResult consent_flow_update_result = 11;
-  optional EmailOptInUpdateResult email_opt_in_update_result = 15;
-}
-
-// Determines which settings sub-pages should be requested to the server.
-message SettingsUiSelector {
-  optional bool about_me_settings = 5;
-  optional ConsentFlowUiSelector consent_flow_ui_selector = 35;
-  optional bool email_opt_in = 43;
-  optional bool gaia_user_context_ui = 54;
-}
+import public "chromeos/ash/services/assistant/public/proto/settings_ui.proto";
diff --git a/chromeos/services/libassistant/BUILD.gn b/chromeos/services/libassistant/BUILD.gn
index 8fb0888c..d00af0e 100644
--- a/chromeos/services/libassistant/BUILD.gn
+++ b/chromeos/services/libassistant/BUILD.gn
@@ -129,6 +129,7 @@
     "//chromeos/ash/components/assistant:buildflags",
     "//chromeos/ash/resources",
     "//chromeos/ash/services/assistant/public/cpp",
+    "//chromeos/ash/services/assistant/public/proto",
     "//chromeos/assistant/internal",
     "//chromeos/assistant/internal:libassistant",
     "//chromeos/assistant/internal:libassistant_shared_headers",
@@ -137,7 +138,6 @@
     "//chromeos/dbus",
     "//chromeos/dbus/power",
     "//chromeos/dbus/util:util",
-    "//chromeos/services/assistant/public/proto",
     "//chromeos/services/libassistant/public/mojom",
     "//chromeos/services/network_config/public/cpp",
     "//chromeos/strings:strings_grit",
diff --git a/chromeos/services/libassistant/settings_controller.cc b/chromeos/services/libassistant/settings_controller.cc
index 0829c55..08987dd 100644
--- a/chromeos/services/libassistant/settings_controller.cc
+++ b/chromeos/services/libassistant/settings_controller.cc
@@ -10,13 +10,13 @@
 #include "base/callback_helpers.h"
 #include "base/sequence_checker.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
+#include "chromeos/ash/services/assistant/public/proto/assistant_device_settings_ui.pb.h"
+#include "chromeos/ash/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/assistant/internal/internal_util.h"
 #include "chromeos/assistant/internal/proto/assistant/display_connection.pb.h"
 #include "chromeos/assistant/internal/proto/shared/proto/settings_ui.pb.h"
 #include "chromeos/assistant/internal/proto/shared/proto/v2/config_settings_interface.pb.h"
 #include "chromeos/assistant/internal/proto/shared/proto/v2/display_interface.pb.h"
-#include "chromeos/services/assistant/public/proto/assistant_device_settings_ui.pb.h"
-#include "chromeos/services/assistant/public/proto/settings_ui.pb.h"
 #include "chromeos/services/libassistant/callback_utils.h"
 #include "chromeos/services/libassistant/grpc/assistant_client.h"
 #include "chromeos/services/libassistant/grpc/utils/settings_utils.h"
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index 0b5758a..b5b3c9d 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -28,6 +28,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/clock.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autofill_download_manager.h"
diff --git a/components/autofill/core/browser/test_autofill_clock.cc b/components/autofill/core/browser/test_autofill_clock.cc
index 41254e32..8b0dc26 100644
--- a/components/autofill/core/browser/test_autofill_clock.cc
+++ b/components/autofill/core/browser/test_autofill_clock.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/test_autofill_clock.h"
 
+#include <memory>
 #include <utility>
 
 #include "base/test/simple_test_clock.h"
@@ -11,22 +12,28 @@
 
 namespace autofill {
 
-TestAutofillClock::TestAutofillClock(base::Time now) {
-  AutofillClock::SetTestClock(&test_clock_);
+TestAutofillClock::TestAutofillClock(base::Time now)
+    : TestAutofillClock(std::make_unique<base::SimpleTestClock>()) {
   SetNow(now);
 }
 
+TestAutofillClock::TestAutofillClock(
+    std::unique_ptr<base::SimpleTestClock> test_clock)
+    : test_clock_(std::move(test_clock)) {
+  AutofillClock::SetTestClock(test_clock_.get());
+}
+
 TestAutofillClock::~TestAutofillClock() {
   // Destroys the test clock and resets a normal clock.
   AutofillClock::SetClock();
 }
 
 void TestAutofillClock::SetNow(base::Time now) {
-  test_clock_.SetNow(now);
+  test_clock_->SetNow(now);
 }
 
 void TestAutofillClock::Advance(base::TimeDelta delta) {
-  test_clock_.Advance(delta);
+  test_clock_->Advance(delta);
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_clock.h b/components/autofill/core/browser/test_autofill_clock.h
index 4fe9201..09f004f3 100644
--- a/components/autofill/core/browser/test_autofill_clock.h
+++ b/components/autofill/core/browser/test_autofill_clock.h
@@ -5,10 +5,12 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_CLOCK_H_
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_CLOCK_H_
 
-#include "base/test/simple_test_clock.h"
+#include <memory>
+
+#include "base/time/time.h"
 
 namespace base {
-class Time;
+class SimpleTestClock;
 }  // namespace base
 
 namespace autofill {
@@ -20,6 +22,7 @@
 class TestAutofillClock {
  public:
   explicit TestAutofillClock(base::Time now = {});
+  explicit TestAutofillClock(std::unique_ptr<base::SimpleTestClock> test_clock);
 
   TestAutofillClock(const TestAutofillClock&) = delete;
   TestAutofillClock& operator=(const TestAutofillClock&) = delete;
@@ -33,7 +36,7 @@
   void Advance(base::TimeDelta delta);
 
  private:
-  base::SimpleTestClock test_clock_;
+  std::unique_ptr<base::SimpleTestClock> test_clock_;
 };
 
 }  // namespace autofill
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc
index 7febc8c..3ea9f2ff 100644
--- a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc
@@ -15,10 +15,12 @@
 #include "base/test/gmock_callback_support.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
+#include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/geo/country_names.h"
+#include "components/autofill/core/browser/test_autofill_clock.h"
 #include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
 #include "components/autofill_assistant/browser/cud_condition.pb.h"
 #include "components/autofill_assistant/browser/field_formatter.h"
@@ -50,16 +52,29 @@
 
 const char kMemoryLocation[] = "address";
 
-class TimeTicksOverride {
+// AutofillClock override that guarantees increasing time.
+class ScopedAutofillClockOverride : public autofill::TestAutofillClock {
  public:
-  static base::TimeTicks Now() { return now_ticks_; }
+  ScopedAutofillClockOverride()
+      : autofill::TestAutofillClock(std::make_unique<IncreasingClock>()) {}
 
-  static base::TimeTicks now_ticks_;
+ private:
+  class IncreasingClock : public base::SimpleTestClock {
+   public:
+    IncreasingClock() { SetNow(base::Time::Now()); }
+
+    IncreasingClock(const IncreasingClock&) = delete;
+    IncreasingClock& operator=(const IncreasingClock&) = delete;
+
+    base::Time Now() const override {
+      return base::SimpleTestClock::Now() + base::Milliseconds(delta_++);
+    }
+
+   private:
+    mutable int delta_ = 0;
+  };
 };
 
-// static
-base::TimeTicks TimeTicksOverride::now_ticks_ = base::TimeTicks::Now();
-
 MATCHER_P(MatchingAutofillVariant, guid, "") {
   if (absl::holds_alternative<const autofill::AutofillProfile*>(arg)) {
     return absl::get<const autofill::AutofillProfile*>(arg)->guid() == guid;
@@ -155,6 +170,15 @@
     ukm::InitializeSourceUrlRecorderForWebContents(web_contents_.get());
     source_id_ = web_contents_->GetPrimaryMainFrame()->GetPageUkmSourceId();
 
+    if (!base::TimeTicks::IsHighResolution()) {
+      // AutofillClock is used to initialize |use_date| for user data created in
+      // tests. |use_date| is expected to be different in each case as clock
+      // time is running. On machines with low resolution clock, we need to
+      // provide a custom autofill clock that ensures always increasing time.
+      autofill_clock_override_ =
+          std::make_unique<ScopedAutofillClockOverride>();
+    }
+
     ON_CALL(mock_action_delegate_, GetPersonalDataManager)
         .WillByDefault(Return(&mock_personal_data_manager_));
     ON_CALL(mock_action_delegate_, GetWebsiteLoginManager)
@@ -225,6 +249,7 @@
   content::RenderViewHostTestEnabler rvh_test_enabler_;
   content::TestBrowserContext browser_context_;
   std::unique_ptr<content::WebContents> web_contents_;
+  std::unique_ptr<ScopedAutofillClockOverride> autofill_clock_override_;
   base::MockCallback<Action::ProcessActionCallback> callback_;
   NiceMock<MockPersonalDataManager> mock_personal_data_manager_;
   NiceMock<MockWebsiteLoginManager> mock_website_login_manager_;
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc
index cec35b8a..2a7a261 100644
--- a/components/cronet/android/cronet_library_loader.cc
+++ b/components/cronet/android/cronet_library_loader.cc
@@ -171,8 +171,7 @@
   // Note: CreateSystemProxyConfigService internally assumes that
   // base::ThreadTaskRunnerHandle::Get() == JNI communication thread.
   std::unique_ptr<net::ProxyConfigService> service =
-      net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
-          io_task_runner);
+      net::ProxyConfigService::CreateSystemProxyConfigService(io_task_runner);
   // If a PAC URL is present, ignore it and use the address and port of
   // Android system's local HTTP proxy server. See: crbug.com/432539.
   // TODO(csharrison) Architect the wrapper better so we don't need to cast for
diff --git a/components/cronet/cronet_global_state_stubs.cc b/components/cronet/cronet_global_state_stubs.cc
index a44ca10..9afd400 100644
--- a/components/cronet/cronet_global_state_stubs.cc
+++ b/components/cronet/cronet_global_state_stubs.cc
@@ -62,7 +62,7 @@
 
 std::unique_ptr<net::ProxyConfigService> CreateProxyConfigService(
     const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) {
-  return net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
+  return net::ProxyConfigService::CreateSystemProxyConfigService(
       io_task_runner);
 }
 
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index 7b40c40..4f7b6ebd 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -102,6 +102,8 @@
     "autocomplete_classifier.h",
     "autocomplete_controller.cc",
     "autocomplete_controller.h",
+    "autocomplete_controller_metrics.cc",
+    "autocomplete_controller_metrics.h",
     "autocomplete_i18n.h",
     "autocomplete_match.cc",
     "autocomplete_match.h",
@@ -583,6 +585,7 @@
     "actions/omnibox_pedal_provider_unittest.cc",
     "actions/omnibox_pedal_unittest.cc",
     "answers_cache_unittest.cc",
+    "autocomplete_controller_metrics_unittest.cc",
     "autocomplete_input_unittest.cc",
     "autocomplete_match_type_unittest.cc",
     "autocomplete_match_unittest.cc",
@@ -594,6 +597,7 @@
     "clipboard_provider_unittest.cc",
     "document_provider_unittest.cc",
     "document_suggestions_service_unittest.cc",
+    "fake_autocomplete_controller.h",
     "favicon_cache_unittest.cc",
     "history_fuzzy_provider_unittest.cc",
     "history_provider_unittest.cc",
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index c5e1c822..205bb23 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -17,7 +17,6 @@
 #include "base/check_op.h"
 #include "base/feature_list.h"
 #include "base/format_macros.h"
-#include "base/metrics/histogram.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/observer_list.h"
 #include "base/ranges/algorithm.h"
@@ -54,7 +53,6 @@
 #include "components/omnibox/browser/voice_suggest_provider.h"
 #include "components/omnibox/browser/zero_suggest_provider.h"
 #include "components/omnibox/browser/zero_suggest_verbatim_match_provider.h"
-#include "components/omnibox/common/omnibox_features.h"
 #include "components/open_from_clipboard/clipboard_recent_content.h"
 #include "components/search_engines/omnibox_focus_type.h"
 #include "components/search_engines/template_url.h"
@@ -447,11 +445,26 @@
 
   // When input.want_asynchronous_matches() is false, the AutocompleteController
   // is being used for text classification, which should not notify observers.
+  // TODO(manukh): This seems unnecessary; `AutocompleteClassifier` and
+  //   `OmniboxController` use separate instances of `AutocompleteController`,
+  //   the former doesn't add observers, the latter always uses
+  //   `want_asynchronous_matches()` set to true. Besides, if that weren't the
+  //   case, e.g. the classifier did add an observer, then
+  //   `AutocompleteController` should respect that, not assume it's a mistake
+  //   and silently ignore the observer. Audit all call paths of `::Start()` to
+  //   remove this check.
   if (input.want_asynchronous_matches()) {
     for (Observer& obs : observers_)
       obs.OnStart(this, input);
   }
 
+  // Must be called before `expire_timer_.Stop()`, modifying `done_`, or
+  // modifying `AutocompleteProvider::done_` below. If the previous request has
+  // not completed, and therefore has not been logged yet, will log it now.
+  // Likewise, if the providers have not completed, and therefore have not been
+  // logged yet, will log them now.
+  metrics_.OnStart();
+
   const std::u16string old_input_text(input_.text());
   const bool old_allow_exact_keyword_match = input_.allow_exact_keyword_match();
   const bool old_want_asynchronous_matches = input_.want_asynchronous_matches();
@@ -479,6 +492,10 @@
   // Start the new query. Starter Pack engines in keyword mode only run a subset
   // of the providers, so call `ShouldRunProvider()` to determine which.
   in_start_ = true;
+  // Use `start_time` rather than `metrics.start_time_` for
+  // 'Omnibox.QueryTime2.*'. They differ by 3 μs, which though too small to be
+  // distinguished in the ms-scale buckets, is large enough to move the
+  // arithmetic mean.
   base::TimeTicks start_time = base::TimeTicks::Now();
   for (const auto& provider : providers_) {
     if (!ShouldRunProvider(provider.get()))
@@ -488,21 +505,27 @@
     provider->Start(input_, minimal_changes);
     if (!input.want_asynchronous_matches())
       DCHECK(provider->done());
+    // `UmaHistogramTimes()` uses 1ms - 10s buckets, whereas this uses 1ms - 5s
+    // buckets.
+    // TODO(crbug.com/1340291|manukh): This isn't handled by `metrics_` yet. It
+    //   will "automatically" move to `metrics_` if we make all providers async.
+    //   Otherwise, if we decide not to make all providers async, move this
+    //   there.
     base::TimeTicks provider_end_time = base::TimeTicks::Now();
-    std::string name =
-        std::string("Omnibox.ProviderTime2.") + provider->GetName();
-    base::HistogramBase* counter = base::Histogram::FactoryGet(
-        name, 1, 5000, 20, base::Histogram::kUmaTargetedHistogramFlag);
-    counter->Add(static_cast<int>(
-        (provider_end_time - provider_start_time).InMilliseconds()));
+    base::UmaHistogramCustomTimes(
+        std::string("Omnibox.ProviderTime2.") + provider->GetName(),
+        provider_end_time - provider_start_time, base::Milliseconds(1),
+        base::Seconds(5), 20);
   }
   if (input.want_asynchronous_matches() && (input.text().length() < 6)) {
+    // `UmaHistogramTimes()` uses 1ms - 10s buckets, whereas this uses 1ms - 1s
+    // buckets.
+    // TODO(crbug.com/1340291|manukh): This isn't handled by `metrics_` yet. Do
+    //   so after we decide whether to make all providers async.
     base::TimeTicks end_time = base::TimeTicks::Now();
-    std::string name =
-        "Omnibox.QueryTime2." + base::NumberToString(input.text().length());
-    base::HistogramBase* counter = base::Histogram::FactoryGet(
-        name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag);
-    counter->Add(static_cast<int>((end_time - start_time).InMilliseconds()));
+    base::UmaHistogramCustomTimes(
+        "Omnibox.QueryTime2." + base::NumberToString(input.text().length()),
+        end_time - start_time, base::Milliseconds(1), base::Seconds(1), 50);
   }
   base::UmaHistogramBoolean("Omnibox.Start.WantAsyncMatches",
                             input.want_asynchronous_matches());
@@ -587,7 +610,7 @@
     match.provider->DeleteMatch(match);
   }
 
-  OnProviderUpdate(true);
+  OnProviderUpdate(true, nullptr);
 
   // If we're not done, we might attempt to redisplay the deleted match. Make
   // sure we aren't displaying it by removing any old entries.
@@ -603,7 +626,7 @@
     match.provider->DeleteMatchElement(match, element_index);
   }
 
-  OnProviderUpdate(true);
+  OnProviderUpdate(true, nullptr);
 }
 
 void AutocompleteController::ExpireCopiedEntries() {
@@ -613,7 +636,15 @@
   UpdateResult(true, false);
 }
 
-void AutocompleteController::OnProviderUpdate(bool updated_matches) {
+void AutocompleteController::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
+  // Should be called even if `in_start_` is true in order to include early
+  // exited async providers. If the provider is done, will log how long the
+  // provider took.
+  if (provider)
+    metrics_.OnProviderUpdate(*provider);
+
   // Providers should only call this method during the asynchronous pass.
   // There's no reason to call this during the synchronous pass, since we
   // perform these operations anyways after all providers are started.
@@ -843,13 +874,12 @@
                                template_url_service_);
   }
 
-  // Log metrics for how many matches are asynchronously changed. If results are
-  // empty then the omnibox is likely closed, and clearing old results won't
-  // be user visible.
-  if (!result_.empty()) {
-    AutocompleteResult::LogUpdateMetrics(last_result_for_logging, result_,
-                                         in_start_);
-  }
+  // Will log metrics for how many matches changed. Will also log timing metrics
+  // for the current request if it's complete; otherwise, will just update
+  // timestamps of when the last update changing any or the default suggestion
+  // occurred.
+  metrics_.OnUpdateResult(last_result_for_logging,
+                          result_.GetMatchDedupComparators());
 
   // Below are all annotations after the match list is ready.
 #if !BUILDFLAG(IS_IOS)
@@ -1149,6 +1179,13 @@
 
 void AutocompleteController::StopHelper(bool clear_result,
                                         bool due_to_user_inactivity) {
+  // Must be called before `expire_timer_.Stop()`, modifying `done_`, or
+  // modifying `AutocompleteProvider::done_` below. If the current request has
+  // not completed, and therefore has not been logged yet, will log it now.
+  // Likewise, if the providers have not completed, and therefore have not been
+  // logged yet, will log them now.
+  metrics_.OnStop();
+
   for (const auto& provider : providers_) {
     if (!ShouldRunProvider(provider.get()))
       continue;
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h
index 9d21f31..c10de784 100644
--- a/components/omnibox/browser/autocomplete_controller.h
+++ b/components/omnibox/browser/autocomplete_controller.h
@@ -19,6 +19,7 @@
 #include "base/timer/timer.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "build/build_config.h"
+#include "components/omnibox/browser/autocomplete_controller_metrics.h"
 #include "components/omnibox/browser/autocomplete_input.h"
 #include "components/omnibox/browser/autocomplete_provider.h"
 #include "components/omnibox/browser/autocomplete_provider_client.h"
@@ -61,7 +62,7 @@
 class AutocompleteController : public AutocompleteProviderListener,
                                public base::trace_event::MemoryDumpProvider {
  public:
-  typedef std::vector<scoped_refptr<AutocompleteProvider> > Providers;
+  typedef std::vector<scoped_refptr<AutocompleteProvider>> Providers;
 
   class Observer : public base::CheckedObserver {
    public:
@@ -153,7 +154,8 @@
   void ExpireCopiedEntries();
 
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   // Called when an omnibox event log entry is generated.
   // Populates |log.provider_info| with diagnostic information about the status
@@ -198,6 +200,12 @@
   const AutocompleteInput& input() const { return input_; }
   const AutocompleteResult& result() const { return result_; }
   bool done() const { return done_; }
+  bool in_start() const { return in_start_; }
+  // TODO(manukh): Once we have a smarter `expire_timer_` that early runs when
+  //  the controller is done, `expire_timer_done()` will be unnecessary. Until
+  //  then, neither, either, or both `done()` and `expire_timer_done()` can be
+  //  true.
+  bool expire_timer_done() const { return !expire_timer_.IsRunning(); }
   const Providers& providers() const { return providers_; }
 
   const base::TimeTicks& last_time_default_match_changed() const {
@@ -213,6 +221,7 @@
   }
 
  private:
+  friend class FakeAutocompleteController;
   friend class AutocompleteProviderTest;
   friend class OmniboxSuggestionButtonRowBrowserTest;
   friend class ZeroSuggestPrefetchTabHelperBrowserTest;
@@ -305,8 +314,7 @@
 
   // Helper function for Stop().  |due_to_user_inactivity| means this call was
   // triggered by a user's idleness, i.e., not an explicit user action.
-  void StopHelper(bool clear_result,
-                  bool due_to_user_inactivity);
+  void StopHelper(bool clear_result, bool due_to_user_inactivity);
 
   // Helper for UpdateKeywordDescriptions(). Returns whether curbing the keyword
   // descriptions is enabled, and whether there is enough input to guarantee
@@ -368,6 +376,8 @@
   // asynchronous provider that returned and changed the default
   // match.  See UpdateResult() for details on when we consider a
   // match to have changed.
+  // This is very similar to `metrics_.last_default_change_time_`, but whereas
+  // that is reset on `::Start()`, this is not.
   base::TimeTicks last_time_default_match_changed_;
 
   // Timer used to remove any matches copied from the last result. When run
@@ -391,6 +401,9 @@
   // boolean is true, we are definitely within the synchronous pass.
   bool in_start_;
 
+  // Logs stability and timing metrics for updates.
+  AutocompleteControllerMetrics metrics_{*this};
+
   // True if the signal predicting a likely search has already been sent to the
   // service worker context during the current input session. False on
   // controller creation and after |ResetSession| is called.
diff --git a/components/omnibox/browser/autocomplete_controller_metrics.cc b/components/omnibox/browser/autocomplete_controller_metrics.cc
new file mode 100644
index 0000000..e6d5a96
--- /dev/null
+++ b/components/omnibox/browser/autocomplete_controller_metrics.cc
@@ -0,0 +1,173 @@
+// 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 "autocomplete_controller_metrics.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/time/time.h"
+#include "components/omnibox/browser/autocomplete_controller.h"
+#include "components/omnibox/browser/autocomplete_provider.h"
+#include "components/omnibox/browser/autocomplete_result.h"
+
+AutocompleteControllerMetrics::AutocompleteControllerMetrics(
+    const AutocompleteController& controller)
+    : controller_(controller) {}
+
+void AutocompleteControllerMetrics::OnStart() {
+  OnStop();
+  logged_finalization_metrics_ = false;
+  start_time_ = base::TimeTicks::Now();
+  last_change_time_ = start_time_;
+  last_default_change_time_ = start_time_;
+}
+
+void AutocompleteControllerMetrics::OnUpdateResult(
+    std::vector<AutocompleteResult::MatchDedupComparator> last_result,
+    std::vector<AutocompleteResult::MatchDedupComparator> new_result) {
+  // If results are empty then the omnibox is likely closed, and clearing old
+  // results won't be user visible. E.g., this occurs when opening a new tab
+  // while the popup was open.
+  if (new_result.empty())
+    return;
+
+  // Log suggestion changes.
+
+  bool any_match_changed_or_removed = false;
+  for (size_t i = 0; i < last_result.size(); ++i) {
+    // Log changed or removed matches. Don't log for matches appended to the
+    // bottom since that's less disruptive.
+    if (i >= new_result.size() || last_result[i] != new_result[i]) {
+      LogSuggestionChangedMetrics(i);
+      any_match_changed_or_removed = true;
+    }
+  }
+  LogAnySuggestionChangedMetrics(any_match_changed_or_removed);
+
+  // Log suggestion finalization times.
+
+  // Only log suggestion finalization metrics for async requests. This handles
+  // logging as soon as the final update occurs, while `OnStop()` handles the
+  // case where the final update never occurs because of interruptions.
+  // TODO(manukh): Consider adding this filter to the above metrics as well.
+  if (!controller_.input().want_asynchronous_matches())
+    return;
+  // E.g., suggestion deletion can call `OnUpdateResult()` after the controller
+  // is done and finalization metrics have been logged. They shouldn't be
+  // re-logged.
+  if (logged_finalization_metrics_)
+    return;
+
+  const bool any_match_changed_or_removed_or_added =
+      any_match_changed_or_removed || last_result.size() != new_result.size();
+  const bool default_match_changed_or_removed_or_added =
+      last_result.empty() || last_result[0] != new_result[0];
+
+  if (any_match_changed_or_removed_or_added)
+    last_change_time_ = base::TimeTicks::Now();
+  if (default_match_changed_or_removed_or_added) {
+    DCHECK(any_match_changed_or_removed_or_added);
+    last_default_change_time_ = last_change_time_;
+  }
+  // It's common to have multiple async updates per input. Only log the final
+  // update.
+  if (ControllerIdle())
+    LogSuggestionFinalizationMetrics();
+}
+
+void AutocompleteControllerMetrics::OnProviderUpdate(
+    const AutocompleteProvider& provider) const {
+  // Some async providers may produce multiple updates. Only log the final async
+  // update.
+  if (provider.done())
+    LogProviderTimeMetrics(provider);
+}
+
+void AutocompleteControllerMetrics::OnStop() {
+  // Done providers should already be logged by `OnProviderUpdate()`.
+  for (const auto& provider : controller_.providers()) {
+    if (!provider->done()) {
+      DCHECK(!controller_.done() || controller_.in_start());
+      LogProviderTimeMetrics(*provider);
+    }
+  }
+
+  // If the controller is done, `OnUpdateResult()` should have already logged
+  // finalization metrics. This case, i.e. `OnStop()` invoked even though the
+  // controller is done, is possible because 1) `OnStart()` calls `OnStop()`
+  // and 2) `AutocompleteController::stop_timer_` may fire after the controller
+  // completes. Checking `!logged_finalization_metrics_` isn't sufficient, as
+  // that would log synchronous inputs.
+  if (!ControllerIdle())
+    LogSuggestionFinalizationMetrics();
+}
+
+bool AutocompleteControllerMetrics::ControllerIdle() {
+  return controller_.done() && controller_.expire_timer_done();
+}
+
+void AutocompleteControllerMetrics::LogSuggestionFinalizationMetrics() {
+  // Should be logged once only, either when all async providers complete
+  // or they're interrupted before completion.
+  DCHECK(!logged_finalization_metrics_);
+  logged_finalization_metrics_ = true;
+
+  const bool done = ControllerIdle();
+  LogAsyncAutocompletionTimeMetrics("Done", done, base::TimeTicks::Now());
+  LogAsyncAutocompletionTimeMetrics("LastChange", done, last_change_time_);
+  LogAsyncAutocompletionTimeMetrics("LastDefaultChange", done,
+                                    last_default_change_time_);
+}
+
+void AutocompleteControllerMetrics::LogProviderTimeMetrics(
+    const AutocompleteProvider& provider) const {
+  LogAsyncAutocompletionTimeMetrics(
+      std::string("Provider.") + provider.GetName(), provider.done(),
+      base::TimeTicks::Now());
+}
+
+void AutocompleteControllerMetrics::LogAsyncAutocompletionTimeMetrics(
+    const std::string& name,
+    bool completed,
+    const base::TimeTicks end_time) const {
+  const auto name_prefix = "Omnibox.AsyncAutocompletionTime." + name;
+  const auto elapsed_time = end_time - start_time_;
+  // These metrics are logged up to about 40 times per omnibox keystroke. But
+  // use UMA functions as the names are dynamic.
+  base::UmaHistogramTimes(name_prefix, elapsed_time);
+  if (completed)
+    base::UmaHistogramTimes(name_prefix + ".Completed", elapsed_time);
+  else
+    base::UmaHistogramTimes(name_prefix + ".Interrupted", elapsed_time);
+}
+
+void AutocompleteControllerMetrics::LogSuggestionChangedMetrics(
+    size_t change_index) const {
+  // These metrics are logged up to about 50 times per omnibox keystroke, so use
+  // UMA macros for efficiency.
+  if (controller_.in_start()) {
+    UMA_HISTOGRAM_EXACT_LINEAR(
+        "Omnibox.CrossInputMatchStability.MatchChange", change_index,
+        AutocompleteResult::kMaxAutocompletePositionValue);
+  } else {
+    UMA_HISTOGRAM_EXACT_LINEAR(
+        "Omnibox.MatchStability.AsyncMatchChange2", change_index,
+        AutocompleteResult::kMaxAutocompletePositionValue);
+  }
+}
+
+void AutocompleteControllerMetrics::LogAnySuggestionChangedMetrics(
+    bool changed) const {
+  // These metrics are logged up to about 5 times per omnibox keystroke, so use
+  // UMA macros for efficiency.
+  if (controller_.in_start()) {
+    UMA_HISTOGRAM_BOOLEAN(
+        "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition", changed);
+  } else {
+    UMA_HISTOGRAM_BOOLEAN(
+        "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition", changed);
+  }
+}
diff --git a/components/omnibox/browser/autocomplete_controller_metrics.h b/components/omnibox/browser/autocomplete_controller_metrics.h
new file mode 100644
index 0000000..7b4eea9
--- /dev/null
+++ b/components/omnibox/browser/autocomplete_controller_metrics.h
@@ -0,0 +1,131 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_CONTROLLER_METRICS_H_
+#define COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_CONTROLLER_METRICS_H_
+
+#include <string>
+
+#include "base/memory/raw_ptr.h"
+#include "components/omnibox/browser/autocomplete_result.h"
+
+class AutocompleteController;
+class AutocompleteProvider;
+
+// Used to track and log timing metrics for `AutocompleteController`. Logs 3
+// sets of metrics:
+// 1) How long until each async provider completes.
+//    - Does not track intermediate updates if an async provider updates results
+//      multiple times.
+//    - Does not track sync providers (i.e., providers that don't use
+//      `AutocompleteProvider::NotifyListeners()` to notify the
+//      `AutocompleteController`.
+//    - Tracks async providers completing syncly (i.e., providers that invoke
+//      `AutocompleteProvider::NotifyListeners()` syncly; see the comment in
+//      `AutocompleteController::OnProviderUpdate()`).
+// 2) How long until the suggestions finalize.
+//    - Does not track sync requests (i.e.,
+//      `AutocompleteInput::set_want_asynchronous_matches()` set to false).
+//    - Does track async requests that complete syncly.
+//    - Tracks suggestion additions, changes, and removals.
+// 3) How many suggestions change during updates.
+//    - Does not track sync request.
+//    - Tracks both sync and async updates.
+//    - Does not track suggestion removals.
+//    - Tracks suggestion additions and changes.
+class AutocompleteControllerMetrics {
+ public:
+  explicit AutocompleteControllerMetrics(
+      const AutocompleteController& controller);
+
+  // Called when `AutocompleteController::Start()` is called. Will 1) log
+  // suggestion finalization metrics for the previous request if it hasn't
+  // already (i.e. if it hasn't completed and is being interrupted), and 2)
+  // reset state to track the new request. Should be called before
+  // `AutocompleteController::done()`,
+  // `::expire_timer_done()`, or `AutocompleteProvider::done()` have been
+  // updated for the new request.
+  void OnStart();
+
+  // Called when `AutocompleteController::UpdateResult()` is called. Will log
+  // metrics on how many suggestions changed with this update. If the controller
+  // is done, will also log suggestion finalization metrics; otherwise, future
+  // calls to `OnProviderUpdate()`, `OnStop()`, or `OnStart()` will log
+  // suggestion finalization metrics.
+  void OnUpdateResult(
+      std::vector<AutocompleteResult::MatchDedupComparator> last_result,
+      std::vector<AutocompleteResult::MatchDedupComparator> new_result);
+
+  // Called when `AutocompleteController::OnProviderUpdate()` is called. If the
+  // provider is done, will log how long it took; otherwise, future calls to
+  // `OnProviderUpdate()`, `OnStop()`, or `OnStart()` will log how long the
+  // provider took.
+  void OnProviderUpdate(const AutocompleteProvider& provider) const;
+
+  // Called when either `AutocompleteController::StopHelper()` or `OnStart()`
+  // are called; i.e., when the ongoing request, if incomplete, will be
+  // interrupted, e.g., because the input was updated, the popup was closed, or
+  // the `AutocompleteController::stop_timer_` expired. Should be called before
+  // `AutocompleteController::done()`, `::expire_timer_done()`, or
+  // `AutocompleteProvider::done()` have been updated.
+  void OnStop();
+
+ private:
+  friend class AutocompleteControllerMetricsTest;
+
+  // Checks `controller_` `done()`, `expire_timer_done()` and `in_start()` to
+  // determine whether the controller is absolutely done; i.e., there won't be
+  // any changes to results until the next user action. Just checking `done()`
+  // isn't sufficient, as the expiring copied matches can change the results.
+  // Just checking `done()` and `expire_timer_done()` isn't sufficient, as
+  // they'll both be true during the sync pass, and all async providers complete
+  // during the sync pass, there won't be a followup async update to trigger
+  // logging metrics.
+  bool ControllerIdle();
+
+  // Logs
+  // 'Omnibox.AsyncAutocompletionTime.[Done|LastChange|LastDefaultChange]'.
+  // Additionally logs either '*.Completed' or '*.Interrupted' for each of the
+  // 3 depending on whether the controller completed or was interrupted.
+  void LogSuggestionFinalizationMetrics();
+
+  // Logs 'Omnibox.AsyncAutocompletionTime.Provider.<provider name>'.
+  // Additionally logs either '*.Completed' or '*.Interrupted' depending
+  // whether the provider completed or was interrupted.
+  void LogProviderTimeMetrics(const AutocompleteProvider& provider) const;
+
+  // Helper for the above 2 logging methods. Logs
+  // 'Omnibox.AsyncAutocompletionTime.<name>'. Additionally logs either
+  // '*.Completed' or '*.Interrupted' depending on `completed`.
+  void LogAsyncAutocompletionTimeMetrics(const std::string& name,
+                                         bool completed,
+                                         const base::TimeTicks end_time) const;
+
+  // Logs 'Omnibox.CrossInputMatchStability.MatchChange' or
+  // 'Omnibox.MatchStability.AsyncMatchChange2' depending on
+  // `controller_.in_start()`.
+  void LogSuggestionChangedMetrics(size_t change_index) const;
+
+  // Logs 'Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition' or
+  // 'Omnibox.MatchStability.AsyncMatchChangedInAnyPosition' depending on
+  // `controller_.in_start()`.
+  void LogAnySuggestionChangedMetrics(bool changed) const;
+
+  const AutocompleteController& controller_;
+
+  // When `OnStart()` was last invoked. Used for measuring latency. Valid even
+  // if `controller_.in_start_` is false.
+  base::TimeTicks start_time_;
+  // When `OnProviderUpdate()` was last invoked and detected any change to the
+  // suggestions.
+  base::TimeTicks last_change_time_;
+  // When `OnProviderUpdate()` was last invoked and detected a change to the
+  // default suggestion.
+  base::TimeTicks last_default_change_time_;
+  // Whether `LogSuggestionFinalizationMetrics()` has been invoked for the
+  // current request.
+  bool logged_finalization_metrics_ = true;
+};
+
+#endif  // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_CONTROLLER_METRICS_H_
diff --git a/components/omnibox/browser/autocomplete_controller_metrics_unittest.cc b/components/omnibox/browser/autocomplete_controller_metrics_unittest.cc
new file mode 100644
index 0000000..bc20581
--- /dev/null
+++ b/components/omnibox/browser/autocomplete_controller_metrics_unittest.cc
@@ -0,0 +1,515 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/omnibox/browser/autocomplete_controller_metrics.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/ranges/algorithm.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "components/omnibox/browser/autocomplete_controller.h"
+#include "components/omnibox/browser/autocomplete_provider_client.h"
+#include "components/omnibox/browser/autocomplete_result.h"
+#include "components/omnibox/browser/autocomplete_scheme_classifier.h"
+#include "components/omnibox/browser/fake_autocomplete_controller.h"
+#include "components/omnibox/browser/fake_autocomplete_provider.h"
+#include "components/omnibox/browser/fake_autocomplete_provider_client.h"
+#include "components/omnibox/browser/fake_tab_matcher.h"
+#include "components/omnibox/browser/tab_matcher.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/metrics_proto/omnibox_input_type.pb.h"
+#include "url/gurl.h"
+
+using testing::ElementsAre;
+using testing::ElementsAreArray;
+
+class AutocompleteControllerMetricsTest : public testing::Test {
+ public:
+  AutocompleteControllerMetricsTest()
+      : metrics_(controller_.metrics_),
+        histogram_tester_(std::make_unique<base::HistogramTester>()){};
+
+  // By default, the controller wants async matches. `SetInputSync()` will
+  // explicitly set this behavior.
+  void SetInputSync(bool sync) {
+    controller_.input_.set_want_asynchronous_matches(!sync);
+  }
+
+  // Mimics `AutocompleteController::Start()`'s behavior. `sync_results_only`
+  // determines whether the controller should be done after the sync pass.
+  // `sync_milliseconds` is how many seconds the sync pass should take.
+  // `old_results` and `sync_results` are passed to
+  // `AutocompleteControllerMetrics::OnUpdateResult()` to determine which
+  // matches changed.
+  void SimulateStart(
+      bool sync_results_only,
+      int sync_milliseconds,
+      std::vector<AutocompleteResult::MatchDedupComparator> old_results,
+      std::vector<AutocompleteResult::MatchDedupComparator> sync_results) {
+    metrics_.OnStart();
+    controller_.in_start_ = true;
+    controller_.done_ = sync_results_only;
+    task_environment_.FastForwardBy(base::Milliseconds(sync_milliseconds));
+    metrics_.OnUpdateResult(old_results, sync_results);
+    controller_.in_start_ = false;
+  }
+
+  // Convenience function to be called before/after EXPECT'ing histograms to
+  // avoid old logs converting new logs.
+  void ResetHistogramTester() {
+    histogram_tester_ = std::make_unique<base::HistogramTester>();
+  }
+
+  // Convenience function to call AutocompleteControllerMetrics::OnStop()` and
+  // expects it to not log any suggestion finalization metrics. Should be used
+  // to simulate the controller completing in which case metrics should have
+  // already been logged earlier during `::OnUpdateResult()`. Should not be used
+  // when the controller is interrupted in which case metrics are expected to be
+  // logged. Does not check provider or cross stability metrics.
+  void StopAndExpectNoSuggestionFinalizationMetrics() {
+    ResetHistogramTester();
+    metrics_.OnStop();
+    ExpectNoSuggestionFinalizationMetrics();
+  }
+
+  // Convenience method to check the buckets of a single metric.
+  void ExpectMetrics(const std::string metric_name,
+                     std::vector<base::Bucket> expected_buckets) {
+    const std::string prefix = "Omnibox.AsyncAutocompletionTime.";
+    EXPECT_THAT(
+        histogram_tester_->GetAllSamples(prefix + metric_name),
+        ElementsAreArray(expected_buckets.data(), expected_buckets.size()))
+        << metric_name;
+  }
+
+  // Convenience method to check the buckets of 3 metrics:
+  // - '...<metric>' will be expected to have `buckets`.
+  // - '...<metric>.[Completed]' will be expected to either have
+  //   `buckets` or be empty, depending on `completed`.
+  void ExpectSlicedMetrics(const std::string& metric,
+                           std::vector<base::Bucket> buckets,
+                           bool completed) {
+    const std::vector<base::Bucket> empty_buckets = {};
+    ExpectMetrics(metric, buckets);
+    ExpectMetrics(metric + ".Completed", completed ? buckets : empty_buckets);
+  }
+
+  // Convenience method to check all 9 suggestion finalization metrics are
+  // empty. '...[Done|LastChange|LastDefaultChange][|.Completed]'
+  void ExpectNoSuggestionFinalizationMetrics() {
+    ExpectSlicedMetrics("Done", {}, false);
+    ExpectSlicedMetrics("LastChange", {}, false);
+    ExpectSlicedMetrics("LastDefaultChange", {}, false);
+  }
+
+  // Convince method to check all 9 suggestion finalization metrics have been
+  // logged exactly once with the correct bucket. This should be used if
+  // there's been a single controller request logged since the last
+  // `ResetHistogramTester()`. If there have been none,
+  // `ExpectNoSuggestionFinalizationMetrics()` should be used.
+  void ExpectSingleCountSuggestionFinalizationMetrics(
+      int done_bucket_min,
+      int last_change_bucket_min,
+      int last_default_change_bucket_min,
+      bool completed) {
+    ExpectSlicedMetrics("Done", {{done_bucket_min, 1}}, completed);
+    ExpectSlicedMetrics("LastChange", {{last_change_bucket_min, 1}}, completed);
+    ExpectSlicedMetrics("LastDefaultChange",
+                        {{last_default_change_bucket_min, 1}}, completed);
+  }
+
+  // Convenience method to check the 3 metrics for a specific provider are
+  // empty. '...Provider.<Provider>[|.Completed]'
+  void ExpectNoProviderMetrics(const std::string& provider) {
+    ExpectSlicedMetrics("Provider." + provider, {}, false);
+  }
+
+  // Convenience method to check the 3 metrics for a specific provider have
+  // been logged exactly once with the correct bucket. This should be used if
+  // there's been a single log for the specified provider since the last
+  // `ResetHistogramTester()`. If there have been none,
+  // `ExpectNoProviderMetrics()` should be used.
+  void ExpectProviderMetrics(const std::string& provider,
+                             int bucket_min,
+                             bool completed) {
+    ExpectSlicedMetrics("Provider." + provider, {{bucket_min, 1}}, completed);
+  }
+
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  // Used to control time passed between calls. Many metrics tested are timing
+  // metrics.
+  FakeAutocompleteController controller_;
+  // A convenience reference to `controller_.metrics_`.
+  AutocompleteControllerMetrics& metrics_;
+  std::unique_ptr<base::HistogramTester> histogram_tester_;
+};
+
+TEST_F(AutocompleteControllerMetricsTest, SuggestionFinalization_SyncInput) {
+  // Sync inputs should not log metrics.
+  SetInputSync(true);
+  SimulateStart(true, 1, {}, {{}});
+  metrics_.OnStop();
+  ExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_OnlySyncUpdate) {
+  // Sync updates should log metrics.
+  SimulateStart(true, 1, {}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(1, 1, 1, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_OnlySyncUpdateWithNoChanges) {
+  // Sync updates without changes should log metrics.
+  SimulateStart(true, 1, {{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(1, 0, 0, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_SyncAnd3AsyncUpdate) {
+  // This is the typical flow: 1 sync update followed by multiple async updates.
+  SimulateStart(false, 1, {}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  // 2nd async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  // Last async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(4, 4, 4, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_SyncAnd3AsyncUpdateWithNoChanges) {
+  // 1 sync and 3 async updates, none of the 4 has a change.
+  SimulateStart(false, 1, {{}}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // 2nd async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // Last async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(4, 0, 0, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(
+    AutocompleteControllerMetricsTest,
+    SuggestionFinalization_UnchangedSyncAnd2UnchangedAnd1ChangedAsyncUpdates) {
+  // 1 sync and 3 async updates, only the last of the 4 has a change.
+  SimulateStart(false, 1, {{}}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // 2nd async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // Last async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(4, 4, 4, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(
+    AutocompleteControllerMetricsTest,
+    SuggestionFinalization_UnchangedSyncAnd1ChangedAnd2UnchangedAsyncUpdates) {
+  // 1 sync and 3 async updates, only the 2nd of the 4 has a change.
+  SimulateStart(false, 1, {{}}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  // 2nd async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // Last async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(4, 2, 2, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_ChangedSyncAnd3UnchangedAsyncUpdates) {
+  // 1 sync and 3 async updates, only the 1st of the 4 has a change.
+  SimulateStart(false, 1, {}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // 2nd async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // Last async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(4, 1, 1, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_StopTimerReached) {
+  // Simulates the case where the async updates take longer than the 1.5s stop
+  // timer. It's not possible for the sync update to take longer, as the stop
+  // timer only starts after the sync update. The logged times should however
+  // measure starting from before the sync update.
+  SimulateStart(false, 1, {}, {{}});
+  // 1st async update.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  // Stop timer.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnStop();
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 1, 1, false);
+  controller_.done_ = true;
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest, SuggestionFinalization_Interrupted) {
+  // Start 1st input.
+  SimulateStart(false, 1, {}, {{}});
+  // 1 async update for 1st input.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  ExpectNoSuggestionFinalizationMetrics();
+  // Interrupted by 2nd input. The log should include the time until
+  // interruption.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  SimulateStart(false, 1, {}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 2, 2, false);
+  // Interrupted by 3rd input.
+  ResetHistogramTester();
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  SimulateStart(false, 1, {}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(2, 1, 1, false);
+  // 1 async update for 3rd input. Controller completes with the 2nd update.
+  ResetHistogramTester();
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  ExpectNoSuggestionFinalizationMetrics();
+  // 2nd and last async update for 3rd input.
+  controller_.done_ = true;
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 3, 3, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       SuggestionFinalization_DefaultUnchanged) {
+  // Sync update.
+  SimulateStart(false, 1, {}, {{}});
+  // 1st async update with non-default match changed.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}, {}});
+  // 2nd async update with no matches changed.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  controller_.done_ = true;
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 2, 1, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+}
+
+TEST_F(AutocompleteControllerMetricsTest, Provider_SyncAndAsyncCompletion) {
+  scoped_refptr<FakeAutocompleteProvider> async_provider_done_sync =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_BOOKMARK);
+  scoped_refptr<FakeAutocompleteProvider> async_provider_done_not_last =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_KEYWORD);
+  scoped_refptr<FakeAutocompleteProvider> async_provider_done_last =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_BUILTIN);
+
+  // Sync update with `async_provider_done_sync` completing.
+  metrics_.OnStart();
+  controller_.in_start_ = true;
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnProviderUpdate(*async_provider_done_sync);
+  ExpectProviderMetrics(async_provider_done_sync->GetName(), 1, true);
+  controller_.done_ = false;
+  metrics_.OnUpdateResult({{}}, {{}});
+  controller_.in_start_ = false;
+  ExpectNoSuggestionFinalizationMetrics();
+  ResetHistogramTester();
+
+  // 1st async update with `async_provider_done_not_last` completing.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnProviderUpdate(*async_provider_done_not_last);
+  ExpectProviderMetrics(async_provider_done_not_last->GetName(), 2, true);
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectNoSuggestionFinalizationMetrics();
+  ResetHistogramTester();
+
+  // Last async update with `async_provider_done_last` completing.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnProviderUpdate(*async_provider_done_last);
+  controller_.done_ = true;
+  ExpectProviderMetrics(async_provider_done_last->GetName(), 3, true);
+  metrics_.OnUpdateResult({{}}, {{}});
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 0, 0, true);
+
+  StopAndExpectNoSuggestionFinalizationMetrics();
+  ExpectNoProviderMetrics(async_provider_done_sync->GetName());
+  ExpectNoProviderMetrics(async_provider_done_not_last->GetName());
+  ExpectNoProviderMetrics(async_provider_done_last->GetName());
+}
+
+TEST_F(AutocompleteControllerMetricsTest,
+       Provider_1ProviderWithMultipleUpdates) {
+  scoped_refptr<FakeAutocompleteProvider> provider =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_BOOKMARK);
+
+  // Sync update without completion.
+  metrics_.OnStart();
+  controller_.in_start_ = true;
+  provider->done_ = false;
+  metrics_.OnProviderUpdate(*provider);
+  controller_.done_ = false;
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnUpdateResult({{}}, {{}});
+  controller_.in_start_ = false;
+
+  // 1st async update without completion.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  metrics_.OnProviderUpdate(*provider);
+  metrics_.OnUpdateResult({{}}, {{}});
+
+  // Last async update with completion.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  provider->done_ = true;
+  controller_.done_ = true;
+  metrics_.OnProviderUpdate(*provider);
+  metrics_.OnUpdateResult({{}}, {{}});
+
+  ExpectProviderMetrics(provider->GetName(), 3, true);
+  ExpectSingleCountSuggestionFinalizationMetrics(3, 0, 0, true);
+  StopAndExpectNoSuggestionFinalizationMetrics();
+  ExpectNoProviderMetrics(provider->GetName());
+}
+
+TEST_F(AutocompleteControllerMetricsTest, Provider_Interrupted) {
+  scoped_refptr<FakeAutocompleteProvider> provider_started =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_BOOKMARK);
+  scoped_refptr<FakeAutocompleteProvider> provider_not_started =
+      new FakeAutocompleteProvider(AutocompleteProvider::Type::TYPE_SEARCH);
+
+  controller_.providers_.push_back(provider_started);
+  controller_.providers_.push_back(provider_not_started);
+
+  // Sync update.
+  SimulateStart(false, 1, {{}}, {{}});
+  // Simulate stopping while `provider_started` is still ongoing.
+  task_environment_.FastForwardBy(base::Milliseconds(1));
+  provider_started->done_ = false;
+  metrics_.OnStop();
+  provider_started->done_ = true;
+  controller_.done_ = true;
+
+  ExpectProviderMetrics(provider_started->GetName(), 2, false);
+  ExpectNoProviderMetrics(provider_not_started->GetName());
+  ExpectSingleCountSuggestionFinalizationMetrics(2, 0, 0, false);
+}
+
+TEST_F(AutocompleteControllerMetricsTest, MatchStability) {
+  auto create_result = [&](std::vector<int> ids) {
+    std::vector<AutocompleteResult::MatchDedupComparator> result;
+    base::ranges::transform(ids, std::back_inserter(result), [](int id) {
+      return std::pair<GURL, bool>{"http://" + base::NumberToString(id), false};
+    });
+    return result;
+  };
+
+  const auto first_result = create_result({0, 1, 2, 3, 4});
+  // Same as `first_result`, but with these changes:
+  //  - Last two matches removed.
+  //  - Default match updated to a new URL.
+  //  - Third match updated to a new URL.
+  const auto second_result = create_result({10, 1, 11});
+  // Same as `second_result`, but with these changes:
+  //  - 2 new matches appended to the bottom.
+  const auto third_result = create_result({10, 1, 11, 10, 2});
+
+  // Verify logging to the Async* histograms.
+  controller_.in_start_ = false;
+  metrics_.OnUpdateResult(first_result, second_result);
+  // Expect the default match, third match, and last two matches to be logged
+  // as changed, and nothing else.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChange2"),
+              testing::ElementsAre(base::Bucket(0, 1), base::Bucket(2, 1),
+                                   base::Bucket(3, 1), base::Bucket(4, 1)));
+  // Expect that we log that at least one of the matches has changed.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
+              testing::ElementsAre(base::Bucket(1, 1)));
+  // Expect that we don't log async updates to the sync histograms.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChange"),
+              testing::ElementsAre());
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
+              testing::ElementsAre());
+  ResetHistogramTester();
+
+  // Verify logging to the CrossInput* histograms.
+  controller_.in_start_ = true;
+  metrics_.OnUpdateResult(first_result, second_result);
+  // Expect the default match, third match, and last two matches to be logged
+  // as changed, and nothing else.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChange"),
+              testing::ElementsAre(base::Bucket(0, 1), base::Bucket(2, 1),
+                                   base::Bucket(3, 1), base::Bucket(4, 1)));
+  // Expect that we log that at least one of the matches has changed.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
+              testing::ElementsAre(base::Bucket(1, 1)));
+  // Expect that we don't log sync updates to the async histograms.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChange2"),
+              testing::ElementsAre());
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
+              testing::ElementsAre());
+  ResetHistogramTester();
+
+  // Verify no logging when appending matches.
+  controller_.in_start_ = false;
+  metrics_.OnUpdateResult(second_result, third_result);
+  controller_.in_start_ = true;
+  metrics_.OnUpdateResult(second_result, third_result);
+  // Expect no changes logged; expect 1 false logged to
+  // *MatchChangedInAnyPosition.
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChange2"),
+              testing::ElementsAre());
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
+              testing::ElementsAre(base::Bucket(0, 1)));
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChange"),
+              testing::ElementsAre());
+  EXPECT_THAT(histogram_tester_->GetAllSamples(
+                  "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
+              testing::ElementsAre(base::Bucket(0, 1)));
+  ResetHistogramTester();
+}
diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc
index 42b4c5c4..21ba9bb 100644
--- a/components/omnibox/browser/autocomplete_provider.cc
+++ b/components/omnibox/browser/autocomplete_provider.cc
@@ -91,7 +91,7 @@
 
 void AutocompleteProvider::NotifyListeners(bool updated_matches) const {
   for (auto* listener : listeners_)
-    listener->OnProviderUpdate(updated_matches);
+    listener->OnProviderUpdate(updated_matches, this);
 }
 
 void AutocompleteProvider::Stop(bool clear_cached_results,
diff --git a/components/omnibox/browser/autocomplete_provider.h b/components/omnibox/browser/autocomplete_provider.h
index 98cdedf..645030f 100644
--- a/components/omnibox/browser/autocomplete_provider.h
+++ b/components/omnibox/browser/autocomplete_provider.h
@@ -357,6 +357,7 @@
 
  protected:
   friend class base::RefCountedThreadSafe<AutocompleteProvider>;
+  friend class FakeAutocompleteProvider;
   FRIEND_TEST_ALL_PREFIXES(BookmarkProviderTest, InlineAutocompletion);
   FRIEND_TEST_ALL_PREFIXES(AutocompleteResultTest,
                            DemoteOnDeviceSearchSuggestions);
diff --git a/components/omnibox/browser/autocomplete_provider_listener.h b/components/omnibox/browser/autocomplete_provider_listener.h
index 9955837..44462299 100644
--- a/components/omnibox/browser/autocomplete_provider_listener.h
+++ b/components/omnibox/browser/autocomplete_provider_listener.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_PROVIDER_LISTENER_H_
 #define COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_PROVIDER_LISTENER_H_
 
+class AutocompleteProvider;
+
 class AutocompleteProviderListener {
  public:
   // Called by a provider as a notification that something has changed.
@@ -19,15 +21,17 @@
   // NOTE: If a provider has finished, it should set done() to true BEFORE
   // calling this method.
   //
-  // NOTE: There's no parameter to tell the listener _which_ provider is
-  // calling it.  Because the AutocompleteController (the typical listener)
-  // doesn't cache the providers' individual matches locally, it has to get
-  // them all again when this is called anyway, so such a parameter wouldn't
-  // actually be useful.
-  virtual void OnProviderUpdate(bool updated_matches) = 0;
+  // `provider` can be null when not called from a provider (e.g., on match
+  // deletion).
+  // TODO(manukh) Perhaps deleting matches shouldn't call `OnProviderUpdate()`.
+  //   Not only is it semantically wrong, but it may also be unnecessary as
+  //   `DeleteMatch()` already duplicates all the work `OnProviderUpdate()`
+  //   does. Though `DeleteMatchElement()` doesn't.
+  virtual void OnProviderUpdate(bool updated_matches,
+                                const AutocompleteProvider* provider) = 0;
 
  protected:
-  virtual ~AutocompleteProviderListener() {}
+  virtual ~AutocompleteProviderListener() = default;
 };
 
 #endif  // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_PROVIDER_LISTENER_H_
diff --git a/components/omnibox/browser/autocomplete_provider_unittest.cc b/components/omnibox/browser/autocomplete_provider_unittest.cc
index 9650f03..e757a863 100644
--- a/components/omnibox/browser/autocomplete_provider_unittest.cc
+++ b/components/omnibox/browser/autocomplete_provider_unittest.cc
@@ -229,8 +229,9 @@
   }
 
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override {
-    controller_->OnProviderUpdate(updated_matches);
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override {
+    controller_->OnProviderUpdate(updated_matches, provider);
     if (closure_)
       closure_.Run();
   }
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 86aa3806..635ef9e2 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -978,40 +978,6 @@
     const std::vector<int>& hidden_group_ids) {
   hidden_group_ids_.insert(hidden_group_ids.begin(), hidden_group_ids.end());
 }
-// static
-void AutocompleteResult::LogUpdateMetrics(
-    const std::vector<MatchDedupComparator>& old_result,
-    const AutocompleteResult& new_result,
-    bool in_start) {
-  bool any_match_changed = false;
-
-  for (size_t i = 0; i < old_result.size(); ++i) {
-    // Log a change for changed or removed matches. Don't log for
-    // matches appended to the bottom since that's less disruptive.
-    if (i >= new_result.size() ||
-        old_result[i] != GetMatchComparisonFields(new_result.match_at(i))) {
-      if (in_start) {
-        UMA_HISTOGRAM_EXACT_LINEAR(
-            "Omnibox.CrossInputMatchStability.MatchChange", i,
-            kMaxAutocompletePositionValue);
-      } else {
-        UMA_HISTOGRAM_EXACT_LINEAR("Omnibox.MatchStability.AsyncMatchChange2",
-                                   i, kMaxAutocompletePositionValue);
-      }
-      any_match_changed = true;
-    }
-  }
-
-  if (in_start) {
-    UMA_HISTOGRAM_BOOLEAN(
-        "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition",
-        any_match_changed);
-  } else {
-    UMA_HISTOGRAM_BOOLEAN(
-        "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition",
-        any_match_changed);
-  }
-}
 
 // static
 bool AutocompleteResult::HasMatchByDestination(const AutocompleteMatch& match,
diff --git a/components/omnibox/browser/autocomplete_result.h b/components/omnibox/browser/autocomplete_result.h
index 617a162..481c69aa 100644
--- a/components/omnibox/browser/autocomplete_result.h
+++ b/components/omnibox/browser/autocomplete_result.h
@@ -243,15 +243,6 @@
 
   void MergeHiddenGroupIds(const std::vector<int>& hidden_group_ids);
 
-  // Logs metrics for when `new_result` replaces `old_result`. `old_result` is a
-  // list of the comparators for the old matches. `in_start` specifies whether
-  // this is during the synchronous initial autocomplete pass of an input or the
-  // subsequent asynchronous passes.
-  static void LogUpdateMetrics(
-      const std::vector<MatchDedupComparator>& old_result,
-      const AutocompleteResult& new_result,
-      bool in_start);
-
   // This method implements a stateful stable partition. Matches which are
   // search types, and their submatches regardless of type, are shifted
   // earlier in the range, while non-search types and their submatches
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc
index 800934e7..a57703e 100644
--- a/components/omnibox/browser/autocomplete_result_unittest.cc
+++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -1115,151 +1115,6 @@
   AssertResultMatches(current_result, result, std::size(result));
 }
 
-// Verify metrics logged for result updates.
-TEST_F(AutocompleteResultTest, LogUpdateMetrics) {
-  AutocompleteInput input(u"a", metrics::OmniboxEventProto::OTHER,
-                          TestSchemeClassifier());
-
-  // Convert `TestData` to `AutocompleteResult`.
-  auto create_result = [&](std::vector<TestData> data,
-                           AutocompleteResult* result) {
-    for (auto& cur_data : data) {
-      AutocompleteMatch match;
-      PopulateAutocompleteMatch(cur_data, &match);
-      match.ComputeStrippedDestinationURL(input, template_url_service_.get());
-      result->AppendMatches({match});
-    }
-  };
-
-  AutocompleteResult first_result;
-  create_result(
-      {
-          {0, 1, 600, true},
-          {1, 1, 500, true},
-          {2, 1, 400, true},
-          {3, 1, 300, true},
-          {4, 1, 200, true},
-      },
-      &first_result);
-  const auto first_comparators = first_result.GetMatchDedupComparators();
-
-  // Same as `first_result`, but with these changes:
-  //  - Last two matches removed.
-  //  - Default match updated to a new URL.
-  //  - Third match updated to a new URL.
-  AutocompleteResult second_result;
-  create_result(
-      {
-          {10, 1, 400, true},
-          {1, 1, 300, true},
-          {11, 1, 200, true},
-      },
-      &second_result);
-  const auto second_comparators = second_result.GetMatchDedupComparators();
-
-  // Same as `second_result`, but with these changes:
-  //  - 2 new matches appended to the bottom.
-  AutocompleteResult third_result;
-  create_result(
-      {
-          {10, 1, 400, true},
-          {1, 1, 300, true},
-          {11, 1, 200, true},
-          {10, 1, 400, true},
-          {2, 1, 200, true},
-      },
-      &third_result);
-
-  // Verify logging to the Async* histograms.
-  {
-    // Constructor takes the snapshot of the current histogram state.
-    base::HistogramTester histograms;
-
-    // Do the logging.
-    AutocompleteResult::LogUpdateMetrics(first_comparators, second_result,
-                                         false);
-
-    // Expect the default match, third match, and last two matches to be logged
-    // as changed, and nothing else.
-    EXPECT_THAT(
-        histograms.GetAllSamples("Omnibox.MatchStability.AsyncMatchChange2"),
-        testing::ElementsAre(base::Bucket(0, 1), base::Bucket(2, 1),
-                             base::Bucket(3, 1), base::Bucket(4, 1)));
-
-    // Expect that we log that at least one of the matches has changed.
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
-                testing::ElementsAre(base::Bucket(1, 1)));
-
-    // Expect that we don't log async updates to the sync histograms.
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.CrossInputMatchStability.MatchChange"),
-                testing::ElementsAre());
-    EXPECT_THAT(
-        histograms.GetAllSamples(
-            "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
-        testing::ElementsAre());
-  }
-
-  // Verify logging to the CrossInput* histograms.
-  {
-    // Constructor takes the snapshot of the current histogram state.
-    base::HistogramTester histograms;
-
-    // Do the logging.
-    AutocompleteResult::LogUpdateMetrics(first_comparators, second_result,
-                                         true);
-
-    // Expect the default match, third match, and last two matches to be logged
-    // as changed, and nothing else.
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.CrossInputMatchStability.MatchChange"),
-                testing::ElementsAre(base::Bucket(0, 1), base::Bucket(2, 1),
-                                     base::Bucket(3, 1), base::Bucket(4, 1)));
-
-    // Expect that we log that at least one of the matches has changed.
-    EXPECT_THAT(
-        histograms.GetAllSamples(
-            "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
-        testing::ElementsAre(base::Bucket(1, 1)));
-
-    // Expect that we don't log sync updates to the async histograms.
-    EXPECT_THAT(
-        histograms.GetAllSamples("Omnibox.MatchStability.AsyncMatchChange2"),
-        testing::ElementsAre());
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
-                testing::ElementsAre());
-  }
-
-  // Verify no logging when appending matches.
-  {
-    // Constructor takes the snapshot of the current histogram state.
-    base::HistogramTester histograms;
-
-    // Do the logging.
-    AutocompleteResult::LogUpdateMetrics(second_comparators, third_result,
-                                         false);
-    AutocompleteResult::LogUpdateMetrics(second_comparators, third_result,
-                                         true);
-
-    // Expect no changes logged; expect 1 false logged to
-    // *MatchChangedInAnyPosition.
-    EXPECT_THAT(
-        histograms.GetAllSamples("Omnibox.MatchStability.AsyncMatchChange2"),
-        testing::ElementsAre());
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"),
-                testing::ElementsAre(base::Bucket(0, 1)));
-    EXPECT_THAT(histograms.GetAllSamples(
-                    "Omnibox.CrossInputMatchStability.MatchChange"),
-                testing::ElementsAre());
-    EXPECT_THAT(
-        histograms.GetAllSamples(
-            "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition"),
-        testing::ElementsAre(base::Bucket(0, 1)));
-  }
-}
 TEST_F(AutocompleteResultTest, DemoteOnDeviceSearchSuggestions) {
   // clang-format off
   TestData data[] = {
diff --git a/components/omnibox/browser/clipboard_provider_unittest.cc b/components/omnibox/browser/clipboard_provider_unittest.cc
index 195ee13..028ae5c 100644
--- a/components/omnibox/browser/clipboard_provider_unittest.cc
+++ b/components/omnibox/browser/clipboard_provider_unittest.cc
@@ -119,7 +119,8 @@
 
  protected:
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   TestSchemeClassifier classifier_;
   FakeClipboardRecentContent clipboard_content_;
@@ -130,7 +131,9 @@
   base::test::TaskEnvironment task_environment_;
 };
 
-void ClipboardProviderTest::OnProviderUpdate(bool updated_matches) {
+void ClipboardProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   // No action required.
 }
 
diff --git a/components/omnibox/browser/document_provider_unittest.cc b/components/omnibox/browser/document_provider_unittest.cc
index 2b349692..f95b5eb 100644
--- a/components/omnibox/browser/document_provider_unittest.cc
+++ b/components/omnibox/browser/document_provider_unittest.cc
@@ -82,7 +82,8 @@
 
  protected:
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   // Set's up |client_| call expectations to enable the doc suggestions; i.e. so
   // that |IsDocumentProviderAllowed()| returns true. This is not necessary when
@@ -144,7 +145,9 @@
   provider_ = DocumentProvider::Create(client_.get(), this, 4);
 }
 
-void DocumentProviderTest::OnProviderUpdate(bool updated_matches) {
+void DocumentProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   // No action required.
 }
 
diff --git a/components/omnibox/browser/fake_autocomplete_controller.h b/components/omnibox/browser/fake_autocomplete_controller.h
new file mode 100644
index 0000000..ff05df4
--- /dev/null
+++ b/components/omnibox/browser/fake_autocomplete_controller.h
@@ -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.
+
+#ifndef COMPONENTS_OMNIBOX_BROWSER_FAKE_AUTOCOMPLETE_CONTROLLER_H_
+#define COMPONENTS_OMNIBOX_BROWSER_FAKE_AUTOCOMPLETE_CONTROLLER_H_
+
+#include "components/omnibox/browser/autocomplete_controller.h"
+#include "components/omnibox/browser/fake_autocomplete_provider_client.h"
+
+class FakeAutocompleteController : public AutocompleteController {
+ public:
+  FakeAutocompleteController()
+      : AutocompleteController(
+            std::make_unique<FakeAutocompleteProviderClient>(),
+            0) {}
+
+  using AutocompleteController::done_;
+  using AutocompleteController::in_start_;
+  using AutocompleteController::input_;
+  using AutocompleteController::metrics_;
+  using AutocompleteController::providers_;
+};
+
+#endif  // COMPONENTS_OMNIBOX_BROWSER_FAKE_AUTOCOMPLETE_CONTROLLER_H_
diff --git a/components/omnibox/browser/fake_autocomplete_provider.h b/components/omnibox/browser/fake_autocomplete_provider.h
index cbbd508..d1679a4a 100644
--- a/components/omnibox/browser/fake_autocomplete_provider.h
+++ b/components/omnibox/browser/fake_autocomplete_provider.h
@@ -19,6 +19,8 @@
   // specific type needed.
   void SetType(Type type) { type_ = type; }
 
+  using AutocompleteProvider::done_;
+
  private:
   ~FakeAutocompleteProvider() override = default;
 };
diff --git a/components/omnibox/browser/history_cluster_provider.cc b/components/omnibox/browser/history_cluster_provider.cc
index c6ac7de..0164e35 100644
--- a/components/omnibox/browser/history_cluster_provider.cc
+++ b/components/omnibox/browser/history_cluster_provider.cc
@@ -56,7 +56,9 @@
   done_ = true;
 }
 
-void HistoryClusterProvider::OnProviderUpdate(bool updated_matches) {
+void HistoryClusterProvider::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   if (done_ || !search_provider_->done())
     return;
   NotifyListeners(CreateMatches());
diff --git a/components/omnibox/browser/history_cluster_provider.h b/components/omnibox/browser/history_cluster_provider.h
index f08c4fd..23fa11b0 100644
--- a/components/omnibox/browser/history_cluster_provider.h
+++ b/components/omnibox/browser/history_cluster_provider.h
@@ -32,7 +32,8 @@
 
   // AutocompleteProviderListener:
   // `HistoryClusterProvider` listens to `SearchProvider` updates.
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
  private:
   ~HistoryClusterProvider() override = default;
diff --git a/components/omnibox/browser/history_cluster_provider_unittest.cc b/components/omnibox/browser/history_cluster_provider_unittest.cc
index 7f375daf..41427c4 100644
--- a/components/omnibox/browser/history_cluster_provider_unittest.cc
+++ b/components/omnibox/browser/history_cluster_provider_unittest.cc
@@ -15,6 +15,7 @@
 #include "components/history_clusters/core/history_clusters_service.h"
 #include "components/history_clusters/core/history_clusters_service_test_api.h"
 #include "components/omnibox/browser/autocomplete_match.h"
+#include "components/omnibox/browser/autocomplete_provider.h"
 #include "components/omnibox/browser/autocomplete_provider_listener.h"
 #include "components/omnibox/browser/fake_autocomplete_provider_client.h"
 #include "components/omnibox/browser/search_provider.h"
@@ -91,7 +92,8 @@
   }
 
   // AutocompleteProviderListener
-  void OnProviderUpdate(bool updated_matches) override {
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override {
     on_provider_update_calls_.push_back(updated_matches);
   };
 
@@ -170,14 +172,14 @@
   // if the search provider is not done when called.
   search_provider_->matches_ = {CreateMatch(u"keyword")};
   provider_->Start(input, false);
-  provider_->OnProviderUpdate(true);
+  provider_->OnProviderUpdate(true, nullptr);
   search_provider_->done_ = true;
   EXPECT_FALSE(provider_->done());
   EXPECT_TRUE(provider_->matches().empty());
 
   // Calling `OnProviderUpdate()` should process search matches if the search
   // provider is done.
-  provider_->OnProviderUpdate(true);
+  provider_->OnProviderUpdate(true, nullptr);
   EXPECT_TRUE(provider_->done());
   ASSERT_EQ(provider_->matches().size(), 1u);
   EXPECT_EQ(provider_->matches()[0].description, u"keyword");
@@ -208,7 +210,7 @@
   provider_->Start(input, false);
   search_provider_->done_ = true;
   EXPECT_FALSE(provider_->done());
-  provider_->OnProviderUpdate(false);
+  provider_->OnProviderUpdate(false, nullptr);
   EXPECT_TRUE(provider_->done());
   EXPECT_TRUE(provider_->matches().empty());
 
@@ -232,12 +234,12 @@
   EXPECT_FALSE(provider_->done());
 
   // Simulate receiving async search matches.
-  provider_->OnProviderUpdate(true);
+  provider_->OnProviderUpdate(true, nullptr);
   EXPECT_FALSE(provider_->done());
 
   // Simulate receiving the last set of async search matches.
   search_provider_->done_ = true;
-  provider_->OnProviderUpdate(true);
+  provider_->OnProviderUpdate(true, nullptr);
   EXPECT_TRUE(provider_->done());
   ASSERT_EQ(provider_->matches().size(), 1u);
   EXPECT_EQ(provider_->matches()[0].description, u"keyword");
@@ -262,7 +264,7 @@
 
   // Simulate receiving async search update with no matches.
   search_provider_->done_ = true;
-  provider_->OnProviderUpdate(false);
+  provider_->OnProviderUpdate(false, nullptr);
   EXPECT_TRUE(provider_->done());
   ASSERT_EQ(provider_->matches().size(), 1u);
 
@@ -280,7 +282,7 @@
   search_provider_->done_ = false;
   provider_->Start(input, false);
   search_provider_->done_ = true;
-  provider_->OnProviderUpdate(false);
+  provider_->OnProviderUpdate(false, nullptr);
   EXPECT_TRUE(provider_->done());
   EXPECT_TRUE(provider_->matches().empty());
 
diff --git a/components/omnibox/browser/history_url_provider_unittest.cc b/components/omnibox/browser/history_url_provider_unittest.cc
index a1aab3b..0813eec 100644
--- a/components/omnibox/browser/history_url_provider_unittest.cc
+++ b/components/omnibox/browser/history_url_provider_unittest.cc
@@ -206,7 +206,8 @@
   HistoryURLProviderTest& operator=(const HistoryURLProviderTest&) = delete;
 
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
  protected:
   // testing::Test
@@ -275,7 +276,9 @@
   }
 };
 
-void HistoryURLProviderTest::OnProviderUpdate(bool updated_matches) {
+void HistoryURLProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   if (autocomplete_->done())
     base::RunLoop::QuitCurrentWhenIdleDeprecated();
 }
diff --git a/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc b/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc
index d2439f4a..416a4d6 100644
--- a/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc
+++ b/components/omnibox/browser/local_history_zero_suggest_provider_unittest.cc
@@ -123,7 +123,8 @@
   }
 
   // AutocompleteProviderListener
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   // Fills the URLDatabase with search URLs using the provided information.
   void LoadURLs(const std::vector<TestURLData>& url_data_list);
@@ -210,7 +211,8 @@
 }
 
 void LocalHistoryZeroSuggestProviderTest::OnProviderUpdate(
-    bool updated_matches) {
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   if (provider_->done() && provider_run_loop_)
     provider_run_loop_->Quit();
 }
diff --git a/components/omnibox/browser/most_visited_sites_provider_unittest.cc b/components/omnibox/browser/most_visited_sites_provider_unittest.cc
index b51eac86..f97c656 100644
--- a/components/omnibox/browser/most_visited_sites_provider_unittest.cc
+++ b/components/omnibox/browser/most_visited_sites_provider_unittest.cc
@@ -131,7 +131,8 @@
                                     size_t index);
 
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   base::HistogramTester histogram_;
   std::unique_ptr<base::test::SingleThreadTaskEnvironment> task_environment_;
@@ -237,7 +238,9 @@
   top_sites_->urls().assign(test_data.begin(), test_data.end());
 }
 
-void MostVisitedSitesProviderTest::OnProviderUpdate(bool updated_matches) {}
+void MostVisitedSitesProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {}
 
 class MostVisitedSitesProviderWithMatchesTest
     : public MostVisitedSitesProviderTest {
diff --git a/components/omnibox/browser/on_device_head_provider_unittest.cc b/components/omnibox/browser/on_device_head_provider_unittest.cc
index b25cdba..6a108bc 100644
--- a/components/omnibox/browser/on_device_head_provider_unittest.cc
+++ b/components/omnibox/browser/on_device_head_provider_unittest.cc
@@ -45,7 +45,8 @@
   }
 
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override {
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override {
     // No action required.
   }
 
diff --git a/components/omnibox/browser/query_tile_provider_unittest.cc b/components/omnibox/browser/query_tile_provider_unittest.cc
index c7c8a8e3..abb5f4ca 100644
--- a/components/omnibox/browser/query_tile_provider_unittest.cc
+++ b/components/omnibox/browser/query_tile_provider_unittest.cc
@@ -40,7 +40,8 @@
 
  protected:
   // AutocompleteProviderListener overrides.
-  void OnProviderUpdate(bool updated_matches) override {}
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override {}
 
   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
 
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc
index 63b44a3..1d7de05 100644
--- a/components/omnibox/browser/zero_suggest_provider_unittest.cc
+++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -100,7 +100,8 @@
 
  protected:
   // AutocompleteProviderListener:
-  void OnProviderUpdate(bool updated_matches) override;
+  void OnProviderUpdate(bool updated_matches,
+                        const AutocompleteProvider* provider) override;
 
   network::TestURLLoaderFactory* test_loader_factory() {
     return client_->test_url_loader_factory();
@@ -161,7 +162,9 @@
       {{OmniboxFieldTrial::kZeroSuggestCacheDurationSec.name, GetParam()}});
 }
 
-void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches) {
+void ZeroSuggestProviderTest::OnProviderUpdate(
+    bool updated_matches,
+    const AutocompleteProvider* provider) {
   provider_did_notify_ = true;
 }
 
diff --git a/components/proxy_config/ios/proxy_service_factory.cc b/components/proxy_config/ios/proxy_service_factory.cc
index cbd5f3a..dcef1de 100644
--- a/components/proxy_config/ios/proxy_service_factory.cc
+++ b/components/proxy_config/ios/proxy_service_factory.cc
@@ -18,7 +18,7 @@
 std::unique_ptr<net::ProxyConfigService>
 ProxyServiceFactory::CreateProxyConfigService(PrefProxyConfigTracker* tracker) {
   std::unique_ptr<net::ProxyConfigService> base_service(
-      net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
+      net::ProxyConfigService::CreateSystemProxyConfigService(
           web::GetIOThreadTaskRunner({})));
   return tracker->CreateTrackingProxyConfigService(std::move(base_service));
 }
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
index d3adfc7..bc9613ad 100644
--- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
+++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -165,6 +165,15 @@
 
 void SegmentationPlatformServiceImpl::OnTrigger(
     std::unique_ptr<TriggerContext> trigger_context) {
+  if (!storage_initialized_) {
+    // If the platform isn't fully initialized, cache the input arguments to run
+    // later.
+    pending_actions_.push_back(base::BindOnce(
+        &SegmentationPlatformServiceImpl::OnTrigger,
+        weak_ptr_factory_.GetWeakPtr(), std::move(trigger_context)));
+    return;
+  }
+
   const TriggerType trigger = trigger_context->trigger_type();
   if (clients_for_trigger_.find(trigger) == clients_for_trigger_.end())
     return;
@@ -242,6 +251,15 @@
     selector.second->OnPlatformInitialized(&execution_service_);
   }
 
+  // Run any method calls that were received during initialization.
+  while (!pending_actions_.empty()) {
+    auto callback = std::move(pending_actions_.front());
+    pending_actions_.pop_front();
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  std::move(callback));
+  }
+
+  // Run any daily maintenance tasks.
   RunDailyTasks(/*is_startup=*/true);
 
   init_time_ = clock_->Now();
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.h b/components/segmentation_platform/internal/segmentation_platform_service_impl.h
index 8073f8c6..076b509d 100644
--- a/components/segmentation_platform/internal/segmentation_platform_service_impl.h
+++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include "base/containers/circular_deque.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/gtest_prod_util.h"
@@ -183,6 +184,9 @@
   const base::Time creation_time_;
   base::Time init_time_;
 
+  // For caching any method calls that were received before initialization.
+  base::circular_deque<base::OnceClosure> pending_actions_;
+
   base::WeakPtrFactory<SegmentationPlatformServiceImpl> weak_ptr_factory_{this};
 };
 
diff --git a/components/services/app_service/public/cpp/app_registry_cache.cc b/components/services/app_service/public/cpp/app_registry_cache.cc
index 58e42f5c..705930d 100644
--- a/components/services/app_service/public/cpp/app_registry_cache.cc
+++ b/components/services/app_service/public/cpp/app_registry_cache.cc
@@ -358,10 +358,10 @@
     auto mojom_app_type = ConvertAppTypeToMojomAppType(app_type);
     in_progress_initialized_app_types_.erase(app_type);
     in_progress_initialized_mojom_app_types_.erase(mojom_app_type);
+    initialized_app_types_.insert(app_type);
     for (auto& obs : observers_) {
       obs.OnAppTypeInitialized(app_type);
     }
-    initialized_app_types_.insert(app_type);
   }
 }
 
diff --git a/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc b/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc
index 511bd515..8070c352 100644
--- a/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_aggregatable_report_golden_unittest.cc
@@ -33,6 +33,7 @@
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_browser_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/numeric/int128.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "third_party/boringssl/src/include/openssl/hpke.h"
@@ -322,6 +323,72 @@
                .BuildAggregatableAttribution(),
        .report_file = "report_1.json",
        .cleartext_payloads_file = "report_1_cleartext_payloads.json"},
+      {.report =
+           ReportBuilder(
+               AttributionInfoBuilder(
+                   SourceBuilder(base::Time::FromJavaTime(1234483200000))
+                       .BuildStored())
+                   .Build())
+               .SetAggregatableHistogramContributions(
+                   {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)})
+               .SetReportTime(base::Time::FromJavaTime(1234486400000))
+               .BuildAggregatableAttribution(),
+       .report_file = "report_2.json",
+       .cleartext_payloads_file = "report_2_cleartext_payloads.json"},
+      {.report =
+           ReportBuilder(
+               AttributionInfoBuilder(
+                   SourceBuilder(base::Time::FromJavaTime(1234483300000))
+                       .SetDebugKey(123)
+                       .BuildStored())
+                   .SetDebugKey(456)
+                   .Build())
+               .SetAggregatableHistogramContributions(
+                   {AggregatableHistogramContribution(/*key=*/1, /*value=*/2),
+                    AggregatableHistogramContribution(/*key=*/3, /*value=*/4)})
+               .SetReportTime(base::Time::FromJavaTime(1234486500000))
+               .BuildAggregatableAttribution(),
+       .report_file = "report_3.json",
+       .cleartext_payloads_file = "report_3_cleartext_payloads.json"},
+      {.report =
+           ReportBuilder(
+               AttributionInfoBuilder(
+                   SourceBuilder(base::Time::FromJavaTime(1234483300000))
+                       .BuildStored())
+                   .Build())
+               .SetAggregatableHistogramContributions(
+                   {AggregatableHistogramContribution(/*key=*/1, /*value=*/2),
+                    AggregatableHistogramContribution(/*key=*/3, /*value=*/4)})
+               .SetReportTime(base::Time::FromJavaTime(1234486500000))
+               .BuildAggregatableAttribution(),
+       .report_file = "report_4.json",
+       .cleartext_payloads_file = "report_4_cleartext_payloads.json"},
+      {.report = ReportBuilder(
+                     AttributionInfoBuilder(
+                         SourceBuilder(base::Time::FromJavaTime(1234483400000))
+                             .SetDebugKey(123)
+                             .BuildStored())
+                         .SetDebugKey(456)
+                         .Build())
+                     .SetAggregatableHistogramContributions(
+                         {AggregatableHistogramContribution(
+                             /*key=*/absl::Uint128Max(), /*value=*/1000)})
+                     .SetReportTime(base::Time::FromJavaTime(1234486600000))
+                     .BuildAggregatableAttribution(),
+       .report_file = "report_5.json",
+       .cleartext_payloads_file = "report_5_cleartext_payloads.json"},
+      {.report = ReportBuilder(
+                     AttributionInfoBuilder(
+                         SourceBuilder(base::Time::FromJavaTime(1234483400000))
+                             .BuildStored())
+                         .Build())
+                     .SetAggregatableHistogramContributions(
+                         {AggregatableHistogramContribution(
+                             /*key=*/absl::Uint128Max(), /*value=*/1000)})
+                     .SetReportTime(base::Time::FromJavaTime(1234486600000))
+                     .BuildAggregatableAttribution(),
+       .report_file = "report_6.json",
+       .cleartext_payloads_file = "report_6_cleartext_payloads.json"},
   };
 
   for (auto& test_case : kTestCases) {
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index b3d247bb..255d333 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -1504,10 +1504,16 @@
       BindServiceWorkerReceiverForOriginAndFrameId(
           &RenderProcessHostImpl::CreateNotificationService, host));
 
+  // This is called when `host` is constructed. ServiceWorkerVersion, which
+  // constructs `host`, checks that context() is not null and also uses
+  // BrowserContext right after constructing `host`, so this is safe.
+  BrowserContext* browser_context =
+      host->version()->context()->wrapper()->browser_context();
+
   // Give the embedder a chance to register binders.
   GetContentClient()
       ->browser()
-      ->RegisterBrowserInterfaceBindersForServiceWorker(map);
+      ->RegisterBrowserInterfaceBindersForServiceWorker(browser_context, map);
 }
 
 void PopulateBinderMap(ServiceWorkerHost* host, mojo::BinderMap* map) {
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 43a91cd..e6006cd 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -440,7 +440,12 @@
   // Create cache storage now as an optimization, so the service worker can
   // use the Cache Storage API immediately on startup.
   if (base::FeatureList::IsEnabled(
-          blink::features::kEagerCacheStorageSetupForServiceWorkers)) {
+          blink::features::kEagerCacheStorageSetupForServiceWorkers) &&
+      // Without COEP, BindCacheStorage won't bind the cache storage,
+      // which make cache storage set up in the install handler get stuck.
+      // Since this is a performance improvement feature, fallback to the slow
+      // path should be better than making the execution get stuck.
+      owner_version_->cross_origin_embedder_policy()) {
     BindCacheStorage(
         params->provider_info->cache_storage.InitWithNewPipeAndPassReceiver());
   }
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index bef77a5..f6af5119 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -497,7 +497,8 @@
 
   void StartWorker(
       blink::mojom::EmbeddedWorkerStartParamsPtr start_params) override {
-    had_cache_storage_ = !!start_params->provider_info->cache_storage;
+    had_cache_storage_ = start_params->provider_info->cache_storage &&
+                         start_params->provider_info->cache_storage.is_valid();
     FakeEmbeddedWorkerInstanceClient::StartWorker(std::move(start_params));
   }
 
@@ -509,14 +510,13 @@
 
 // Test that the worker is given a CacheStoragePtr during startup.
 TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      blink::features::kEagerCacheStorageSetupForServiceWorkers);
-
   const GURL scope("http://example.com/");
   const GURL url("http://example.com/worker.js");
 
   RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+  // We should set COEP, or cache storage pipe won't be made.
+  pair.second->set_cross_origin_embedder_policy(
+      network::CrossOriginEmbedderPolicy());
   auto worker = std::make_unique<EmbeddedWorkerInstance>(pair.second.get());
 
   // Start the worker.
diff --git a/content/browser/service_worker/service_worker_host.cc b/content/browser/service_worker/service_worker_host.cc
index b587a6d..fe98d06 100644
--- a/content/browser/service_worker/service_worker_host.cc
+++ b/content/browser/service_worker/service_worker_host.cc
@@ -89,8 +89,6 @@
 void ServiceWorkerHost::BindCacheStorage(
     mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(!base::FeatureList::IsEnabled(
-      blink::features::kEagerCacheStorageSetupForServiceWorkers));
   version_->embedded_worker()->BindCacheStorage(std::move(receiver));
 }
 
diff --git a/content/browser/service_worker/service_worker_host.h b/content/browser/service_worker/service_worker_host.h
index 08b3bc0..ec13602 100644
--- a/content/browser/service_worker/service_worker_host.h
+++ b/content/browser/service_worker/service_worker_host.h
@@ -83,7 +83,8 @@
 
   void CreateWebTransportConnector(
       mojo::PendingReceiver<blink::mojom::WebTransportConnector> receiver);
-  // Used only when EagerCacheStorageSetupForServiceWorkers is disabled.
+  // Used when EagerCacheStorageSetupForServiceWorkers is disabled, or when
+  // setup for eager cache storage has failed.
   void BindCacheStorage(
       mojo::PendingReceiver<blink::mojom::CacheStorage> receiver);
 
diff --git a/content/browser/snapshot_browsertest.cc b/content/browser/snapshot_browsertest.cc
index 51dd6024..54741d7 100644
--- a/content/browser/snapshot_browsertest.cc
+++ b/content/browser/snapshot_browsertest.cc
@@ -253,17 +253,14 @@
 //   Linux TSAN Tests
 // See crbug.com/771119
 // TODO(https://crbug.com/1317446): Fix and enable on Fuchsia.
-#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || (BUILDFLAG(IS_CHROMEOS_ASH)) || \
-    ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) &&                        \
-     defined(THREAD_SANITIZER)) ||                                             \
+#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || BUILDFLAG(IS_CHROMEOS_ASH) || \
+    ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) &&                      \
+     defined(THREAD_SANITIZER)) ||                                           \
     BUILDFLAG(IS_FUCHSIA)
 #define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest
-#define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
 #else
 #define MAYBE_SyncMultiWindowTest SyncMultiWindowTest
-#define MAYBE_AsyncMultiWindowTest AsyncMultiWindowTest
 #endif
-
 IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
   SetupTestServer();
 
@@ -315,6 +312,22 @@
   }
 }
 
+// Timing out either all the time, or infrequently, apparently because
+// they're too slow, on the following configurations:
+//   Windows Debug
+//   Linux Chromium OS ASAN LSAN Tests (1)
+//   Linux TSAN Tests
+// See crbug.com/771119
+// TODO(crbug.com/1164581): recently crashes flakily on
+// linux_chromium_asan_rel_ng and linux-rel.
+// TODO(https://crbug.com/1317446): Fix and enable on Fuchsia.
+#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || BUILDFLAG(IS_CHROMEOS_ASH) || \
+    (BUILDFLAG(IS_CHROMEOS) && defined(THREAD_SANITIZER)) ||                 \
+    BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA)
+#define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
+#else
+#define MAYBE_AsyncMultiWindowTest AsyncMultiWindowTest
+#endif
 IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
   SetupTestServer();
 
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 2f8923e..0d79069d 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1184,6 +1184,7 @@
   // Allows to register browser interfaces which are exposed to a service worker
   // execution context.
   virtual void RegisterBrowserInterfaceBindersForServiceWorker(
+      BrowserContext* browser_context,
       mojo::BinderMapWithContext<const ServiceWorkerVersionBaseInfo&>* map) {}
 
   // Allows the embedder to register per-WebUI interface brokers that are used
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json
new file mode 100644
index 0000000..a1dbb336
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2.json
@@ -0,0 +1,7 @@
+{
+   "aggregation_service_payloads": [ {
+      "key_id": "example_id",
+      "payload": "dCYizN7JKoWWZDpuozgMKeByzoe/IpsVMhelP8l2pmad+TDXg2ozkr7wTGtrnzzV9QO6IpC1HD1fE4zmVK887kGj3yKKFDffRtB61g5DwMwW9ZrBJYvYP5doz4JV/R5QKwpgM5gmvAEa+PXT1R7h"
+   } ],
+   "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2_cleartext_payloads.json
new file mode 100644
index 0000000..bc85911f
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_2_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAWlvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json
new file mode 100644
index 0000000..fe2f3da5
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3.json
@@ -0,0 +1,11 @@
+{
+    "aggregation_service_payloads": [ {
+       "debug_cleartext_payload": "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt",
+       "key_id": "example_id",
+       "payload": "YgUBhtua0jsHvbFxd8ROeg97SI5Qelu4ykXRBIdoUSW2SH7ES5Dq4VrlFJL28J2Ly0tzlbMfzvdKqTLcEATjUaWaQ9Ncg8HQ8tnoghdxzql5vS/MTwbgiY/TDqi3EgbOIiCd//7pnH5dAD+WIgpstlZZUBiJQKlu5C0YDSWOuoLwK+VTs+Tc9SYFq4zdJSGVA7tA"
+    } ],
+    "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}",
+    "source_debug_key": "123",
+    "trigger_debug_key": "456"
+}
+ 
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3_cleartext_payloads.json
new file mode 100644
index 0000000..c3578b044
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_3_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json
new file mode 100644
index 0000000..ecaf02f
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4.json
@@ -0,0 +1,7 @@
+{
+    "aggregation_service_payloads": [ {
+       "key_id": "example_id",
+       "payload": "LiavspqLWGHPnexW5xtuLXVMb2oNNBrrhULpOrBR4TGKnKCxL9qdKTyqzSJlkztvG8lDG2eQnxMwRl0lwKu4T157wwYHLpt0VxWBArFUeNh18QP5WihW7z3+UYkNQN3PJ7ddwoDe60X5UiQ6fxdUKT7F0mOIb/bAjKYKvUd8QukUBCvxTLdGmrWj22+OR239nRAO"
+    } ],
+    "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4_cleartext_payloads.json
new file mode 100644
index 0000000..c3578b044
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_4_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json
new file mode 100644
index 0000000..beee9df
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5.json
@@ -0,0 +1,10 @@
+{
+    "aggregation_service_payloads": [ {
+       "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt",
+       "key_id": "example_id",
+       "payload": "s6tBRv9QuDDKxi4/yT2/JGys+gxnzqVic33u8ungNBo03u/kQhhZd4tGiOubxUHQwliP+PPiSymQwapcWuDvPM2+ajGXY/sY6fQXuMg0KIuYUOkguNPM5ZwcIxCiCJ2Brbv8MtGy2ZuCHQ176xPh"
+    } ],
+    "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"debug_mode\":\"enabled\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}",
+    "source_debug_key": "123",
+    "trigger_debug_key": "456"
+} 
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5_cleartext_payloads.json
new file mode 100644
index 0000000..26be6de
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_5_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json
new file mode 100644
index 0000000..520fed7
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6.json
@@ -0,0 +1,7 @@
+{
+    "aggregation_service_payloads": [ {
+       "key_id": "example_id",
+       "payload": "IQuLGiKuR9tcUrq3nWuJ7Qy6VrtQSKNDUgflzyuIkT1R6kagnjxsYVMhrw3j9euUQaSlK9jYfg070Z+GMIGYjRwsVUGnCbmTROH30zrB1ar2hupppnvl0Hz2Xkbv9ZjoVCmuV97RuQP506JqYyj7"
+    } ],
+    "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://conversion.test\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"source_registration_time\":\"1234483200\",\"version\":\"0.1\"}"
+} 
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6_cleartext_payloads.json
new file mode 100644
index 0000000..26be6de
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/latest/report_6_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2.json
new file mode 100644
index 0000000..114ec20
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2.json
@@ -0,0 +1,10 @@
+{
+  "aggregation_service_payloads": [ {
+     "key_id": "example_id",
+     "payload": "eXr+bRdXPiUmHsh/Dn0MKTALoJI6/LTzcZ4cUZiXmjFcVaojbQT+fzj+Wmfrg9qFecZbddTMMT4hkBXow+fxLyuLGgOfN++2c7oEijuqPLLBUQYHHhsxfdx9i/DzP6G7OVb7XvsvuB9q5MGDGesg"
+  } ],
+  "attribution_destination": "https://conversion.test",
+  "shared_info": "{\"privacy_budget_key\":\"aOEbtVxG8dYzAR2K/xuW/OppNaQikp5RdjAXshOQ9w8=\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486400\",\"version\":\"\"}",
+  "source_registration_time": "1234483200",
+  "source_site": "https://impression.test"
+}
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2_cleartext_payloads.json
new file mode 100644
index 0000000..bc85911f
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_2_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAWlvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3.json
new file mode 100644
index 0000000..75b7bfb
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3.json
@@ -0,0 +1,13 @@
+{
+  "aggregation_service_payloads": [ {
+     "debug_cleartext_payload": "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt",
+     "key_id": "example_id",
+     "payload": "zxdMIx1NKDOndRaLGkyzx7f28Mxw7xicACB/9cbYCibLDv7JDxmx+fScuuVOUziz874o4/hmOHU546wtzo9wSXM2QhPY9fmH4jTAwBOz7azvC6pqX8pJrjqxl6AjOG0JRSa3mBz3m4SOVPl9EuGSpb5imA9s4a1cqBtrgS3QxLjnd3LCihK/Mgc3m5PVhk9X+Iz5"
+  } ],
+  "attribution_destination": "https://conversion.test",
+  "shared_info": "{\"debug_mode\":\"enabled\",\"privacy_budget_key\":\"aOEbtVxG8dYzAR2K/xuW/OppNaQikp5RdjAXshOQ9w8=\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"version\":\"\"}",
+  "source_debug_key": "123",
+  "source_registration_time": "1234483200",
+  "source_site": "https://impression.test",
+  "trigger_debug_key": "456"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3_cleartext_payloads.json
new file mode 100644
index 0000000..c3578b044
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_3_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4.json
new file mode 100644
index 0000000..45884bd
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4.json
@@ -0,0 +1,10 @@
+{
+  "aggregation_service_payloads": [ {
+     "key_id": "example_id",
+     "payload": "0xJTQXpWySmhg30YZCaa7WoEoDskHoyOxa4P3g3DJAUaEjBX1WWFinKZ53P9GlX6y/nDufrtgPPXDhgQd6n8ujkpItzahUQCgRxuACEbNctbY94+rYRuRqXuOByi+OXOtN5RpCBnHXhxTGLv4+hVF0pLLWybTS6LiX15VykhK0KiQzjMqeV2fv0da/52YdC7FApQ"
+  } ],
+  "attribution_destination": "https://conversion.test",
+  "shared_info": "{\"privacy_budget_key\":\"aOEbtVxG8dYzAR2K/xuW/OppNaQikp5RdjAXshOQ9w8=\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486500\",\"version\":\"\"}",
+  "source_registration_time": "1234483200",
+  "source_site": "https://impression.test"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4_cleartext_payloads.json
new file mode 100644
index 0000000..c3578b044
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_4_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgqJldmFsdWVEAAAAAmZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAaJldmFsdWVEAAAABGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAA2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5.json
new file mode 100644
index 0000000..8914905
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5.json
@@ -0,0 +1,13 @@
+{
+  "aggregation_service_payloads": [ {
+     "debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt",
+     "key_id": "example_id",
+     "payload": "C87AumVqWwJd8+S82/hGj9CFrIJGTVg7R6ioUeFa+UhnxI9yUB7UQJcFg5LN0LTdi1dGTHtZM85c6ObeVWMkSUDWIDaR3lDjpL3l+utAfseAb/mSPBA5CAw6snudGctUPTF+0uQALSW1QnuPLgM+"
+  } ],
+  "attribution_destination": "https://conversion.test",
+  "shared_info": "{\"debug_mode\":\"enabled\",\"privacy_budget_key\":\"aOEbtVxG8dYzAR2K/xuW/OppNaQikp5RdjAXshOQ9w8=\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"version\":\"\"}",
+  "source_debug_key": "123",
+  "source_registration_time": "1234483200",
+  "source_site": "https://impression.test",
+  "trigger_debug_key": "456"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5_cleartext_payloads.json
new file mode 100644
index 0000000..26be6de
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_5_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6.json
new file mode 100644
index 0000000..b646303
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6.json
@@ -0,0 +1,10 @@
+{
+  "aggregation_service_payloads": [ {
+     "key_id": "example_id",
+     "payload": "IczoOtZk7tC/cBhFlc7tYZj0zaZqfB5RvQ2uWPeufFMf4XW7qyOhw7GfrP2+HtycNkgtY4qWTxJZeg7LsQiDcltXIvoUGvBe0mb9Ygu//uVhn1a/NTlD9nvDlgoxzpSpQvEaOKoqIElZ/0LTvRsZ"
+  } ],
+  "attribution_destination": "https://conversion.test",
+  "shared_info": "{\"privacy_budget_key\":\"aOEbtVxG8dYzAR2K/xuW/OppNaQikp5RdjAXshOQ9w8=\",\"report_id\":\"21abd97f-73e8-4b88-9389-a9fee6abda5e\",\"reporting_origin\":\"https://report.test\",\"scheduled_report_time\":\"1234486600\",\"version\":\"\"}",
+  "source_registration_time": "1234483200",
+  "source_site": "https://impression.test"
+}
diff --git a/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6_cleartext_payloads.json b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6_cleartext_payloads.json
new file mode 100644
index 0000000..26be6de
--- /dev/null
+++ b/content/test/data/attribution_reporting/aggregatable_report_goldens/version_/report_6_cleartext_payloads.json
@@ -0,0 +1,3 @@
+[
+  "omRkYXRhgaJldmFsdWVEAAAD6GZidWNrZXRQ/////////////////////2lvcGVyYXRpb25paGlzdG9ncmFt"
+]
\ No newline at end of file
diff --git a/extensions/browser/api/offscreen/offscreen_api.cc b/extensions/browser/api/offscreen/offscreen_api.cc
index afaa0ed5..26d189e 100644
--- a/extensions/browser/api/offscreen/offscreen_api.cc
+++ b/extensions/browser/api/offscreen/offscreen_api.cc
@@ -63,6 +63,8 @@
     ExtensionHost* host) {
   SendResponseToExtension(
       Error("Offscreen document closed before fully loading."));
+  // The host is destroyed, so ensure we're no longer observing it.
+  DCHECK(!host_observer_.IsObserving());
 }
 
 void OffscreenCreateDocumentFunction::OnExtensionHostDidStopFirstLoad(
@@ -75,8 +77,81 @@
   DCHECK(browser_context())
       << "SendResponseToExtension() should never be called after context "
       << "shutdown";
+
+  // Even though the function is destroyed after responding to the extension,
+  // this process happens asynchronously. Stop observing the host now to avoid
+  // any chance of being notified of future events.
+  host_observer_.Reset();
+
   Respond(std::move(response_value));
   Release();  // Balanced in Run().
 }
 
+OffscreenCloseDocumentFunction::OffscreenCloseDocumentFunction() = default;
+OffscreenCloseDocumentFunction::~OffscreenCloseDocumentFunction() = default;
+
+ExtensionFunction::ResponseAction OffscreenCloseDocumentFunction::Run() {
+  EXTENSION_FUNCTION_VALIDATE(extension());
+
+  OffscreenDocumentManager* manager =
+      OffscreenDocumentManager::Get(browser_context());
+  OffscreenDocumentHost* offscreen_document =
+      manager->GetOffscreenDocumentForExtension(*extension());
+  if (!offscreen_document)
+    return RespondNow(Error("No current offscreen document."));
+
+  host_observer_.Observe(offscreen_document);
+
+  // Add a reference so that we can respond to the extension once the
+  // offscreen document finishes closing.
+  // Balanced in either `OnBrowserContextShutdown()` or
+  // `SendResponseToExtension()`.
+  AddRef();
+  manager->CloseOffscreenDocumentForExtension(*extension());
+
+  return RespondLater();
+}
+
+void OffscreenCloseDocumentFunction::OnBrowserContextShutdown() {
+  // Release dangling lifetime pointers and bail. No point in responding now;
+  // the context is shutting down. Reset `host_observer_` first to allay any
+  // re-entrancy concerns about the host being destructed at this point.
+  host_observer_.Reset();
+  Release();  // Balanced in Run().
+}
+
+void OffscreenCloseDocumentFunction::OnExtensionHostDestroyed(
+    ExtensionHost* host) {
+  SendResponseToExtension(NoArguments());
+  // The host is destroyed, so ensure we're no longer observing it.
+  DCHECK(!host_observer_.IsObserving());
+}
+
+void OffscreenCloseDocumentFunction::SendResponseToExtension(
+    ResponseValue response_value) {
+  DCHECK(browser_context())
+      << "SendResponseToExtension() should never be called after context "
+      << "shutdown";
+
+  // Even though the function is destroyed after responding to the extension,
+  // this process happens asynchronously. Stop observing the host now to avoid
+  // any chance of being notified of future events.
+  host_observer_.Reset();
+
+  Respond(std::move(response_value));
+  Release();  // Balanced in Run().
+}
+
+OffscreenHasDocumentFunction::OffscreenHasDocumentFunction() = default;
+OffscreenHasDocumentFunction::~OffscreenHasDocumentFunction() = default;
+
+ExtensionFunction::ResponseAction OffscreenHasDocumentFunction::Run() {
+  EXTENSION_FUNCTION_VALIDATE(extension());
+
+  bool has_document =
+      OffscreenDocumentManager::Get(browser_context())
+          ->GetOffscreenDocumentForExtension(*extension()) != nullptr;
+  return RespondNow(OneArgument(base::Value(has_document)));
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/api/offscreen/offscreen_api.h b/extensions/browser/api/offscreen/offscreen_api.h
index f8e7604..cfa949a6 100644
--- a/extensions/browser/api/offscreen/offscreen_api.h
+++ b/extensions/browser/api/offscreen/offscreen_api.h
@@ -46,6 +46,57 @@
       this};
 };
 
+class OffscreenCloseDocumentFunction : public ExtensionFunction,
+                                       public ExtensionHostObserver {
+ public:
+  DECLARE_EXTENSION_FUNCTION("offscreen.closeDocument",
+                             OFFSCREEN_CLOSEDOCUMENT);
+
+  OffscreenCloseDocumentFunction();
+  OffscreenCloseDocumentFunction(const OffscreenCloseDocumentFunction&) =
+      delete;
+  OffscreenCloseDocumentFunction& operator=(
+      const OffscreenCloseDocumentFunction&) = delete;
+
+  // ExtensionFunction:
+  ResponseAction Run() override;
+
+ private:
+  ~OffscreenCloseDocumentFunction() override;
+
+  // ExtensionFunction:
+  void OnBrowserContextShutdown() override;
+
+  // ExtensionHostObserver:
+  void OnExtensionHostDestroyed(ExtensionHost* host) override;
+
+  // Sends a reply asynchronously to the extension.
+  void SendResponseToExtension(ResponseValue response_value);
+
+  // Observes the newly-created document to wait for it to be ready.
+  base::ScopedObservation<ExtensionHost, ExtensionHostObserver> host_observer_{
+      this};
+};
+
+class OffscreenHasDocumentFunction : public ExtensionFunction,
+                                     public ExtensionHostObserver {
+ public:
+  // Note: We use `UNKNOWN` as the histogram value here because we are unlikely
+  // to ship this API to stable.
+  DECLARE_EXTENSION_FUNCTION("offscreen.hasDocument", UNKNOWN);
+
+  OffscreenHasDocumentFunction();
+  OffscreenHasDocumentFunction(const OffscreenHasDocumentFunction&) = delete;
+  OffscreenHasDocumentFunction& operator=(const OffscreenHasDocumentFunction&) =
+      delete;
+
+  // ExtensionFunction:
+  ResponseAction Run() override;
+
+ private:
+  ~OffscreenHasDocumentFunction() override;
+};
+
 }  // namespace extensions
 
 #endif  // EXTENSIONS_BROWSER_API_OFFSCREEN_OFFSCREEN_API_H_
diff --git a/extensions/browser/api/offscreen/offscreen_document_manager.cc b/extensions/browser/api/offscreen/offscreen_document_manager.cc
index 8976ffc6..e7cb5d0 100644
--- a/extensions/browser/api/offscreen/offscreen_document_manager.cc
+++ b/extensions/browser/api/offscreen/offscreen_document_manager.cc
@@ -132,6 +132,13 @@
   data.host = std::make_unique<OffscreenDocumentHost>(extension,
                                                       site_instance.get(), url);
   OffscreenDocumentHost* host = data.host.get();
+
+  // The following Unretained() is safe because this class owns the offscreen
+  // document host, so it can't possibly be called after the manager's
+  // destruction.
+  host->SetCloseHandler(
+      base::BindOnce(&OffscreenDocumentManager::CloseOffscreenDocument,
+                     base::Unretained(this)));
   host->CreateRendererSoon();
 
   return host;
@@ -146,6 +153,12 @@
   return iter->second.host.get();
 }
 
+void OffscreenDocumentManager::CloseOffscreenDocumentForExtension(
+    const Extension& extension) {
+  DCHECK_NE(nullptr, GetOffscreenDocumentForExtension(extension));
+  offscreen_documents_.erase(extension.id());
+}
+
 void OffscreenDocumentManager::OnExtensionUnloaded(
     content::BrowserContext* browser_context,
     const Extension* extension,
@@ -162,4 +175,12 @@
   offscreen_documents_.clear();
 }
 
+void OffscreenDocumentManager::CloseOffscreenDocument(
+    ExtensionHost* offscreen_document) {
+  auto iter = offscreen_documents_.find(offscreen_document->extension_id());
+  DCHECK(iter != offscreen_documents_.end());
+  DCHECK_EQ(iter->second.host.get(), offscreen_document);
+  offscreen_documents_.erase(iter);
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/api/offscreen/offscreen_document_manager.h b/extensions/browser/api/offscreen/offscreen_document_manager.h
index 42dd8c7..7e5d5e65 100644
--- a/extensions/browser/api/offscreen/offscreen_document_manager.h
+++ b/extensions/browser/api/offscreen/offscreen_document_manager.h
@@ -20,6 +20,7 @@
 
 namespace extensions {
 class Extension;
+class ExtensionHost;
 class ProcessManager;
 class OffscreenDocumentHost;
 
@@ -53,6 +54,10 @@
   OffscreenDocumentHost* GetOffscreenDocumentForExtension(
       const Extension& extension);
 
+  // Closes the current offscreen document. Note: This requires that there *is*
+  // an active offscreen document.
+  void CloseOffscreenDocumentForExtension(const Extension& extension);
+
  private:
   struct OffscreenDocumentData {
     // Appease Chromium clang plugin with out-of-line ctors/dtors.
@@ -75,6 +80,9 @@
   // KeyedService:
   void Shutdown() override;
 
+  // Closes the specified `offscreen_document`.
+  void CloseOffscreenDocument(ExtensionHost* offscreen_document);
+
   // The collection of offscreen documents, mapped to extension ID.
   std::map<ExtensionId, OffscreenDocumentData> offscreen_documents_;
 
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 03cc8dd..d295762 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1743,6 +1743,7 @@
   PASSWORDSPRIVATE_STARTAUTOMATEDPASSWORDCHANGE = 1680,
   OFFSCREEN_CREATEDOCUMENT = 1681,
   PASSWORDSPRIVATE_REFRESHSCRIPTSIFNECESSARY = 1682,
+  OFFSCREEN_CLOSEDOCUMENT = 1683,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/common/api/offscreen.idl b/extensions/common/api/offscreen.idl
index e67c34b..00409e0b 100644
--- a/extensions/common/api/offscreen.idl
+++ b/extensions/common/api/offscreen.idl
@@ -21,6 +21,7 @@
   };
 
   callback VoidCallback = void();
+  callback BooleanCallback = void(boolean result);
 
   interface Functions {
     // Creates a new offscreen document for the extension.
@@ -30,5 +31,18 @@
     [supportsPromises] static void createDocument(
         CreateParameters parameters,
         VoidCallback callback);
+
+    // Closes the currently-open offscreen document for the extension.
+    // |callback|: Invoked when the offscreen document has been closed.
+    [supportsPromises] static void closeDocument(VoidCallback callback);
+
+    // Determines whether the extension has an active document.
+    // TODO(https://crbug.com/1339382): This probably isn't something we want to
+    // ship in its current form (hence the nodoc). Instead of this, we should
+    // integrate offscreen documents into a service worker-compatible getViews()
+    // alternative. But this is pretty useful in testing environments.
+    // |callback|: Invoked with the result of whether the extension has an
+    // active offscreen document.
+    [supportsPromises, nodoc] static void hasDocument(BooleanCallback callback);
   };
 };
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc
index 60c33124..ea2f3463 100644
--- a/headless/lib/browser/headless_request_context_manager.cc
+++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -16,7 +16,7 @@
 #include "headless/lib/browser/headless_browser_context_options.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "net/http/http_auth_preferences.h"
-#include "net/proxy_resolution/configured_proxy_resolution_service.h"
+#include "net/proxy_resolution/proxy_config_service.h"
 #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
 #include "services/network/network_service.h"
 #include "services/network/public/cpp/features.h"
@@ -98,8 +98,7 @@
     // We must create the proxy config service on the UI loop on Linux because
     // it must synchronously run on the glib message loop.
     proxy_config_service_ =
-        net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
-            task_runner_);
+        net::ProxyConfigService::CreateSystemProxyConfigService(task_runner_);
     task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&net::ProxyConfigService::AddObserver,
                                   base::Unretained(proxy_config_service_.get()),
diff --git a/infra/config/generated/builders/ci/android-fieldtrial-rel/properties.json b/infra/config/generated/builders/ci/android-fieldtrial-rel/properties.json
index 48cd90f7..56b88cd0 100644
--- a/infra/config/generated/builders/ci/android-fieldtrial-rel/properties.json
+++ b/infra/config/generated/builders/ci/android-fieldtrial-rel/properties.json
@@ -45,7 +45,7 @@
       ],
       "mirroring_builder_group_and_names": [
         {
-          "builder": "android-fieldtrial-fyi-rel",
+          "builder": "android-fieldtrial-rel",
           "group": "tryserver.chromium.android"
         }
       ]
diff --git a/infra/config/generated/builders/try/android-fieldtrial-fyi-rel/properties.json b/infra/config/generated/builders/try/android-fieldtrial-rel/properties.json
similarity index 100%
rename from infra/config/generated/builders/try/android-fieldtrial-fyi-rel/properties.json
rename to infra/config/generated/builders/try/android-fieldtrial-rel/properties.json
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 2de20c24..aa5d9a8 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -532,7 +532,7 @@
         includable_only: true
       }
       builders {
-        name: "chromium/try/android-fieldtrial-fyi-rel"
+        name: "chromium/try/android-fieldtrial-rel"
         includable_only: true
       }
       builders {
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index ffea57e0..3758598 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -21050,10 +21050,6 @@
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21135,10 +21131,6 @@
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21220,10 +21212,6 @@
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -21307,10 +21295,6 @@
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
-        key: "luci.buildbucket.omit_python2"
-        value: 100
-      }
-      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
@@ -50814,7 +50798,7 @@
       }
     }
     builders {
-      name: "android-fieldtrial-fyi-rel"
+      name: "android-fieldtrial-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
       dimensions: "cores:8"
@@ -50839,7 +50823,7 @@
         '    }'
         '  },'
         '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/try/android-fieldtrial-fyi-rel/properties.json",'
+        '    "properties_file": "infra/config/generated/builders/try/android-fieldtrial-rel/properties.json",'
         '    "top_level_project": {'
         '      "ref": "refs/heads/main",'
         '      "repo": {'
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 3539e22..1c6c9cc 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -15831,7 +15831,7 @@
     name: "buildbucket/luci.chromium.try/android-deterministic-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/android-fieldtrial-fyi-rel"
+    name: "buildbucket/luci.chromium.try/android-fieldtrial-rel"
   }
   builders {
     name: "buildbucket/luci.chromium.try/android-inverse-fieldtrials-pie-x86-fyi-rel"
@@ -16944,7 +16944,7 @@
     name: "buildbucket/luci.chromium.try/android-deterministic-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/android-fieldtrial-fyi-rel"
+    name: "buildbucket/luci.chromium.try/android-fieldtrial-rel"
   }
   builders {
     name: "buildbucket/luci.chromium.try/android-inverse-fieldtrials-pie-x86-fyi-rel"
diff --git a/infra/config/subprojects/chromium/ci/chromium.win.star b/infra/config/subprojects/chromium/ci/chromium.win.star
index ef018bd..15bbe95 100644
--- a/infra/config/subprojects/chromium/ci/chromium.win.star
+++ b/infra/config/subprojects/chromium/ci/chromium.win.star
@@ -87,9 +87,6 @@
     ),
     cores = 32,
     os = os.WINDOWS_ANY,
-    experiments = {
-        "luci.buildbucket.omit_python2": 100,
-    },
 )
 
 ci.builder(
@@ -115,9 +112,6 @@
     ),
     cores = 32,
     os = os.WINDOWS_ANY,
-    experiments = {
-        "luci.buildbucket.omit_python2": 100,
-    },
 )
 
 ci.builder(
@@ -253,9 +247,6 @@
     cores = 32,
     cq_mirrors_console_view = "mirrors",
     os = os.WINDOWS_ANY,
-    experiments = {
-        "luci.buildbucket.omit_python2": 100,
-    },
 )
 
 ci.builder(
@@ -286,9 +277,6 @@
     cores = 32,
     cq_mirrors_console_view = "mirrors",
     os = os.WINDOWS_ANY,
-    experiments = {
-        "luci.buildbucket.omit_python2": 100,
-    },
 )
 
 ci.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
index cd4c7db..05c4058 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -219,7 +219,7 @@
 )
 
 try_.builder(
-    name = "android-fieldtrial-fyi-rel",
+    name = "android-fieldtrial-rel",
     mirrors = ["ci/android-fieldtrial-rel"],
 )
 
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 4c34e11..a9027ed 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b8399b5c625e5e5efea5d7d142b56768bf0d0a25
\ No newline at end of file
+22d10ad7b9f1c1bc6505a5f6cf3f8d7384b5881a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 152c652a..77500bd 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-30d671c5e016cf480744c992b9b7bdafc6f29c23
\ No newline at end of file
+3e83087d1c7e3c24352b4fdb827e4dbb44de9092
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index b48a96f..ac4ce4a 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-3e858fb8ac1d945860cb2ac1ce2b75b5a72ea81d
\ No newline at end of file
+00b9a2d8183eddf6451496b25240e88b288825d5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 41ccab1a..7119d35 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-310089929f12a68289f272524c5e2f652ee83502
\ No newline at end of file
+26cfa039365e055bcfcf578d832f7e05bd35e03e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 42936b9..c1a1b9a 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-9e12741c59237b385598efcf2da887987c19f2b3
\ No newline at end of file
+b356b9764452388cddb89a928c2b5b8ac3cdc051
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index fc398e2b..4185eee 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ae824b7d2d7667ae31fa42320b4b29bc14ec4b20
\ No newline at end of file
+a243d5e7a72a5102819db8219389cb72a16d7efa
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 4d8be1ecf..6f397a3 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-12312a6f1c8b95fe9a1d6225786969d813148d00
\ No newline at end of file
+7bd5638e1535adda4b5bd1c681a6b12e09a7702e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 155f910..9c0e7c4 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-078ca45e3aba5b09e29ede9d300dcd87983ee457
\ No newline at end of file
+f4c3e21587555fc4459dac3ea936c6930bb22b92
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 2673ad1c..01cd567 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-9039ff7de4d4b16e9650ad6eaf714b10ff53a167
\ No newline at end of file
+f36b1d64d6e480bbbd3f7e787470de2785be9729
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 0b5bbe41..a93a6ae 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-3faf388de96439187dcdaceddd8385f1e46a829f
\ No newline at end of file
+54e8bfad5b01ff6e1b0c2e55de5c72af483a770d
\ No newline at end of file
diff --git a/media/base/video_types.cc b/media/base/video_types.cc
index d909bf5..fc60c99 100644
--- a/media/base/video_types.cc
+++ b/media/base/video_types.cc
@@ -151,6 +151,51 @@
   return false;
 }
 
+bool IsRGB(VideoPixelFormat format) {
+  switch (format) {
+    case PIXEL_FORMAT_ARGB:
+    case PIXEL_FORMAT_XRGB:
+    case PIXEL_FORMAT_RGB24:
+    case PIXEL_FORMAT_ABGR:
+    case PIXEL_FORMAT_XBGR:
+    case PIXEL_FORMAT_XR30:
+    case PIXEL_FORMAT_XB30:
+    case PIXEL_FORMAT_BGRA:
+    case PIXEL_FORMAT_RGBAF16:
+      return true;
+
+    case PIXEL_FORMAT_UNKNOWN:
+    case PIXEL_FORMAT_I420:
+    case PIXEL_FORMAT_YV12:
+    case PIXEL_FORMAT_I422:
+    case PIXEL_FORMAT_I420A:
+    case PIXEL_FORMAT_I444:
+    case PIXEL_FORMAT_NV12:
+    case PIXEL_FORMAT_NV21:
+    case PIXEL_FORMAT_UYVY:
+    case PIXEL_FORMAT_YUY2:
+    case PIXEL_FORMAT_MJPEG:
+    case PIXEL_FORMAT_YUV420P9:
+    case PIXEL_FORMAT_YUV420P10:
+    case PIXEL_FORMAT_YUV422P9:
+    case PIXEL_FORMAT_YUV422P10:
+    case PIXEL_FORMAT_YUV444P9:
+    case PIXEL_FORMAT_YUV444P10:
+    case PIXEL_FORMAT_YUV420P12:
+    case PIXEL_FORMAT_YUV422P12:
+    case PIXEL_FORMAT_YUV444P12:
+    case PIXEL_FORMAT_Y16:
+    case PIXEL_FORMAT_P016LE:
+    case PIXEL_FORMAT_I422A:
+    case PIXEL_FORMAT_I444A:
+    case PIXEL_FORMAT_YUV420AP10:
+    case PIXEL_FORMAT_YUV422AP10:
+    case PIXEL_FORMAT_YUV444AP10:
+      return false;
+  }
+  return false;
+}
+
 bool IsOpaque(VideoPixelFormat format) {
   switch (format) {
     case PIXEL_FORMAT_UNKNOWN:
diff --git a/media/base/video_types.h b/media/base/video_types.h
index dca783b..519502bb 100644
--- a/media/base/video_types.h
+++ b/media/base/video_types.h
@@ -110,6 +110,9 @@
 // Returns true if |format| is a YUV format with multiple planes.
 MEDIA_SHMEM_EXPORT bool IsYuvPlanar(VideoPixelFormat format);
 
+// Returns true if |format| is an RGB format.
+MEDIA_SHMEM_EXPORT bool IsRGB(VideoPixelFormat format);
+
 // Returns true if |format| has no Alpha channel (hence is always opaque).
 MEDIA_SHMEM_EXPORT bool IsOpaque(VideoPixelFormat format);
 
diff --git a/media/formats/hls/parse_status.cc b/media/formats/hls/parse_status.cc
index e22fa66..113e240 100644
--- a/media/formats/hls/parse_status.cc
+++ b/media/formats/hls/parse_status.cc
@@ -24,6 +24,8 @@
     PARSE_STATUS_CODE_CASE(kFailedToParseDecimalResolution);
     PARSE_STATUS_CODE_CASE(kFailedToParseQuotedString);
     PARSE_STATUS_CODE_CASE(kFailedToParseByteRange);
+    PARSE_STATUS_CODE_CASE(kFailedToParseStableId);
+    PARSE_STATUS_CODE_CASE(kFailedToParseInstreamId);
     PARSE_STATUS_CODE_CASE(kInvalidPlaylistVersion);
     PARSE_STATUS_CODE_CASE(kUnknownPlaylistType);
     PARSE_STATUS_CODE_CASE(kMalformedAttributeList);
diff --git a/media/formats/hls/parse_status.h b/media/formats/hls/parse_status.h
index 01a9bc4..f6bebeb 100644
--- a/media/formats/hls/parse_status.h
+++ b/media/formats/hls/parse_status.h
@@ -21,6 +21,8 @@
   kFailedToParseDecimalResolution,
   kFailedToParseQuotedString,
   kFailedToParseByteRange,
+  kFailedToParseStableId,
+  kFailedToParseInstreamId,
   kInvalidPlaylistVersion,
   kUnknownPlaylistType,
   kMalformedAttributeList,
diff --git a/media/formats/hls/types.cc b/media/formats/hls/types.cc
index 082fea1..a3dc0ce 100644
--- a/media/formats/hls/types.cc
+++ b/media/formats/hls/types.cc
@@ -8,8 +8,11 @@
 #include <cmath>
 #include <limits>
 
+#include "base/containers/contains.h"
 #include "base/no_destructor.h"
+#include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "media/formats/hls/parse_status.h"
 #include "media/formats/hls/source_string.h"
 #include "third_party/re2/src/re2/re2.h"
@@ -25,6 +28,10 @@
   return to_re2(str.Str());
 }
 
+bool IsOneOf(char c, base::StringPiece set) {
+  return base::Contains(set, c);
+}
+
 // Returns the substring matching a valid AttributeName, advancing `source_str`
 // to the following character. If no such substring exists, returns
 // `absl::nullopt` and leaves `source_str` untouched. This is like matching the
@@ -34,17 +41,7 @@
 
   // Returns whether the given char is permitted in an AttributeName
   const auto is_char_valid = [](char c) -> bool {
-    if (c >= 'A' && c <= 'Z') {
-      return true;
-    }
-    if (c >= '0' && c <= '9') {
-      return true;
-    }
-    if (c == '-') {
-      return true;
-    }
-
-    return false;
+    return base::IsAsciiUpper(c) || base::IsAsciiDigit(c) || c == '-';
   };
 
   // Extract the substring where `is_char_valid` succeeds
@@ -98,20 +95,7 @@
   // This returns whether a given char is permitted in an unquoted attribute
   // value.
   const auto is_char_valid = [](char c) -> bool {
-    if (c >= 'a' && c <= 'z') {
-      return true;
-    }
-    if (c >= 'A' && c <= 'Z') {
-      return true;
-    }
-    if (c >= '0' && c <= '9') {
-      return true;
-    }
-    if (c == '-' || c == '_' || c == '.') {
-      return true;
-    }
-
-    return false;
+    return base::IsAsciiAlphaNumeric(c) || IsOneOf(c, "-_.");
   };
 
   const char* end =
@@ -425,7 +409,51 @@
     return ParseStatusCode::kMalformedVariableName;
   }
 
-  return VariableName{source_str.Str()};
+  return VariableName(source_str.Str());
+}
+
+ParseStatus::Or<StableId> StableId::Parse(ResolvedSourceString str) {
+  const auto is_char_valid = [](char c) -> bool {
+    return base::IsAsciiAlphaNumeric(c) || IsOneOf(c, "+/=.-_");
+  };
+
+  if (str.Empty() || !base::ranges::all_of(str.Str(), is_char_valid)) {
+    return ParseStatusCode::kFailedToParseStableId;
+  }
+
+  return StableId(std::string{str.Str()});
+}
+
+ParseStatus::Or<InstreamId> InstreamId::Parse(ResolvedSourceString str) {
+  constexpr base::StringPiece kCcStr = "CC";
+  constexpr base::StringPiece kServiceStr = "SERVICE";
+
+  // Parse the type (one of 'CC' or 'SERVICE')
+  Type type;
+  uint8_t max;
+  if (base::StartsWith(str.Str(), kCcStr)) {
+    type = Type::kCc;
+    max = 4;
+    str.Consume(kCcStr.size());
+  } else if (base::StartsWith(str.Str(), kServiceStr)) {
+    type = Type::kService;
+    max = 63;
+    str.Consume(kServiceStr.size());
+  } else {
+    return ParseStatusCode::kFailedToParseInstreamId;
+  }
+
+  // Parse the number, max allowed value depends on the type
+  auto number_result = ParseDecimalInteger(str);
+  if (number_result.has_error()) {
+    return ParseStatusCode::kFailedToParseInstreamId;
+  }
+  auto number = std::move(number_result).value();
+  if (number < 1 || number > max) {
+    return ParseStatusCode::kFailedToParseInstreamId;
+  }
+
+  return InstreamId(type, static_cast<uint8_t>(number));
 }
 
 }  // namespace media::hls::types
diff --git a/media/formats/hls/types.h b/media/formats/hls/types.h
index 2426442..e02b5c6 100644
--- a/media/formats/hls/types.h
+++ b/media/formats/hls/types.h
@@ -182,6 +182,43 @@
   base::StringPiece name_;
 };
 
+// Represents a string that is guaranteed to be non-empty, and consisting only
+// of characters in the set {[a-z], [A-Z], [0-9], +, /, =, ., -, _}.
+// This is used in the 'STABLE-VARIANT-ID' and 'STABLE-RENDITION-ID' attributes
+// of the EXT-X-STREAM-INF and EXT-X-MEDIA tags, respectively.
+class MEDIA_EXPORT StableId {
+ public:
+  static ParseStatus::Or<StableId> Parse(ResolvedSourceString str);
+
+  const std::string& Str() const { return id_; }
+
+ private:
+  explicit StableId(std::string id) : id_(std::move(id)) {}
+
+  std::string id_;
+};
+
+// Represents the contents of the 'INSTREAM-ID' attribute on the 'EXT-X-MEDIA'
+// tag.
+class MEDIA_EXPORT InstreamId {
+ public:
+  enum class Type {
+    kCc,
+    kService,
+  };
+
+  static ParseStatus::Or<InstreamId> Parse(ResolvedSourceString);
+
+  Type GetType() const { return type_; }
+  uint8_t GetNumber() const { return number_; }
+
+ private:
+  InstreamId(Type type, uint8_t number) : type_(type), number_(number) {}
+
+  Type type_;
+  uint8_t number_;
+};
+
 }  // namespace media::hls::types
 
 #endif  // MEDIA_FORMATS_HLS_TYPES_H_
diff --git a/media/formats/hls/types_unittest.cc b/media/formats/hls/types_unittest.cc
index 574369e..a5cdd69 100644
--- a/media/formats/hls/types_unittest.cc
+++ b/media/formats/hls/types_unittest.cc
@@ -765,4 +765,105 @@
   ok_test(9223372036854775807u, 9223372036854775808u);
 }
 
+TEST(HlsTypesTest, ParseStableId) {
+  constexpr auto ok_test = [](base::StringPiece x,
+                              const base::Location& from =
+                                  base::Location::Current()) {
+    auto result =
+        types::StableId::Parse(ResolvedSourceString::CreateForTesting(x));
+    ASSERT_TRUE(result.has_value()) << from.ToString();
+    auto value = std::move(result).value();
+    EXPECT_EQ(value.Str(), x);
+  };
+  constexpr auto error_test = [](base::StringPiece x,
+                                 const base::Location& from =
+                                     base::Location::Current()) {
+    auto result =
+        types::StableId::Parse(ResolvedSourceString::CreateForTesting(x));
+    ASSERT_TRUE(result.has_error()) << from.ToString();
+    EXPECT_EQ(std::move(result).error().code(),
+              ParseStatusCode::kFailedToParseStableId)
+        << from.ToString();
+  };
+
+  // StableId may not be empty
+  error_test("");
+
+  // StableId may not contain whitespace
+  error_test("hello world");
+  error_test(" world");
+  error_test("world ");
+  error_test("hello\tworld");
+
+  // StableId may not contain certain characters
+  error_test("hello&world");
+  error_test("hello*world");
+  error_test("hello,world");
+
+  ok_test("hello_world");
+  ok_test("HELLO_WORLD");
+  ok_test("HELLO_WORLD123");
+  ok_test("123HELLO/WORLD");
+  ok_test("HELLO=WORLD");
+  ok_test("H3Llo.World");
+  ok_test("-/HELLO+World");
+}
+
+TEST(HlsTypesTest, ParseInstreamId) {
+  constexpr auto ok_test =
+      [](base::StringPiece x, types::InstreamId::Type type, uint8_t number,
+         const base::Location& from = base::Location::Current()) {
+        auto result =
+            types::InstreamId::Parse(ResolvedSourceString::CreateForTesting(x));
+        ASSERT_TRUE(result.has_value()) << from.ToString();
+        auto value = std::move(result).value();
+        EXPECT_EQ(value.GetType(), type) << from.ToString();
+        EXPECT_EQ(value.GetNumber(), number) << from.ToString();
+      };
+  constexpr auto error_test = [](base::StringPiece x,
+                                 const base::Location& from =
+                                     base::Location::Current()) {
+    auto result =
+        types::InstreamId::Parse(ResolvedSourceString::CreateForTesting(x));
+    ASSERT_TRUE(result.has_error()) << from.ToString();
+    EXPECT_EQ(std::move(result).error().code(),
+              ParseStatusCode::kFailedToParseInstreamId)
+        << from.ToString();
+  };
+
+  // InstreamId may not be empty
+  error_test("");
+
+  // InstreamId is case-sensitive
+  error_test("cc1");
+  error_test("Cc1");
+  error_test("cC1");
+  error_test("service1");
+  error_test("Service1");
+
+  // InstreamId may not contain spaces
+  error_test(" CC1");
+  error_test("CC1 ");
+  error_test("CC 1");
+  error_test(" SERVICE1");
+  error_test("SERVICE1 ");
+  error_test("SERVICE 1");
+
+  // Min/Max allowed value depends on type
+  error_test("CC0");
+  error_test("CC-1");
+  error_test("CC1.5");
+  error_test("CC5");
+  error_test("SERVICE0");
+  error_test("SERVICE-1");
+  error_test("SERVICE1.5");
+  error_test("SERVICE64");
+
+  // Test some valid inputs
+  ok_test("CC1", types::InstreamId::Type::kCc, 1);
+  ok_test("CC4", types::InstreamId::Type::kCc, 4);
+  ok_test("SERVICE1", types::InstreamId::Type::kService, 1);
+  ok_test("SERVICE63", types::InstreamId::Type::kService, 63);
+}
+
 }  // namespace media::hls
diff --git a/media/gpu/windows/d3d11_decoder_configurator.h b/media/gpu/windows/d3d11_decoder_configurator.h
index c6c8c14..8e5adfc 100644
--- a/media/gpu/windows/d3d11_decoder_configurator.h
+++ b/media/gpu/windows/d3d11_decoder_configurator.h
@@ -55,8 +55,6 @@
   const GUID DecoderGuid() const { return decoder_guid_; }
   DXGI_FORMAT TextureFormat() const { return dxgi_format_; }
 
-  static constexpr size_t BUFFER_COUNT = 20;
-
  private:
   // Set up instances of the parameter structs for D3D11 Functions
   void SetUpDecoderDescriptor(const gfx::Size& coded_size);
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc
index 4669bea..114c080f 100644
--- a/media/gpu/windows/d3d11_video_decoder.cc
+++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -735,15 +735,20 @@
 
   ComD3D11Texture2D in_texture;
 
+  // In addition to what the decoder needs, add one picture buffer
+  // for overlay weirdness, just to be safe. We may need to track
+  // actual used buffers for all use cases and decide an optimal
+  // number of picture buffers.
+  size_t pic_buffers_required =
+      accelerated_video_decoder_->GetRequiredNumOfPictures() + 1;
+
   // Create each picture buffer.
-  for (size_t i = 0; i < D3D11DecoderConfigurator::BUFFER_COUNT; i++) {
+  for (size_t i = 0; i < pic_buffers_required; i++) {
     // Create an input texture / texture array if we haven't already.
     if (!in_texture) {
       auto result = decoder_configurator_->CreateOutputTexture(
           device_, size,
-          use_single_video_decoder_texture_
-              ? 1
-              : D3D11DecoderConfigurator::BUFFER_COUNT,
+          use_single_video_decoder_texture_ ? 1 : pic_buffers_required,
           texture_selector_->DoesDecoderOutputUseSharedHandle());
       if (result.has_value()) {
         in_texture = std::move(result).value();
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index 14ea906..2a32c1d 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -887,9 +887,10 @@
                 << VideoPixelFormatToString(video_frame->format());
     return external_resources;
   }
-  if (external_resources.type == VideoFrameResourceType::RGB ||
-      external_resources.type == VideoFrameResourceType::RGBA ||
-      external_resources.type == VideoFrameResourceType::RGBA_PREMULTIPLIED) {
+  if ((external_resources.type == VideoFrameResourceType::RGB ||
+       external_resources.type == VideoFrameResourceType::RGBA ||
+       external_resources.type == VideoFrameResourceType::RGBA_PREMULTIPLIED) &&
+      IsRGB(video_frame->format())) {
     resource_color_space = resource_color_space.GetAsFullRangeRGB();
   }
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 2ad3eecf..1ba9000 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -747,6 +747,7 @@
     "proxy_resolution/proxy_bypass_rules.h",
     "proxy_resolution/proxy_config.cc",
     "proxy_resolution/proxy_config.h",
+    "proxy_resolution/proxy_config_service.cc",
     "proxy_resolution/proxy_config_service.h",
     "proxy_resolution/proxy_config_service_fixed.cc",
     "proxy_resolution/proxy_config_service_fixed.h",
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index 6f28dba..c79a9013 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -3523,6 +3523,27 @@
 EVENT_TYPE(RESOURCE_SCHEDULER_REQUEST_STARTED)
 
 // -----------------------------------------------------------------------------
+// Auxiliary network service in-memory HTTP cache related events
+// -----------------------------------------------------------------------------
+
+// This event is emitted when HTTP response headers are served from the
+// in-memory cache.
+// The following parameters are attached:
+//   {
+//     "headers": <The list of header:value pairs>,
+//   }
+EVENT_TYPE(IN_MEMORY_CACHE_READ_RESPONSE_HEADERS)
+
+// This event is emitted when response content are read from the in-memory
+// cache.
+// The following parameters are attached:
+//   {
+//     "byte_count": <Number of bytes that were just sent>,
+//     "bytes": <The exact bytes sent, Base64 encoded>,
+//   }
+EVENT_TYPE(IN_MEMORY_CACHE_BYTES_READ)
+
+// -----------------------------------------------------------------------------
 // Network Quality Estimator related events
 // -----------------------------------------------------------------------------
 
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.cc b/net/proxy_resolution/configured_proxy_resolution_service.cc
index 6c18fe5e..00521eb 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service.cc
+++ b/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -45,18 +45,11 @@
 #include "net/url_request/url_request_context.h"
 
 #if BUILDFLAG(IS_WIN)
-#include "net/proxy_resolution/win/proxy_config_service_win.h"
 #include "net/proxy_resolution/win/proxy_resolver_winhttp.h"
 #elif BUILDFLAG(IS_IOS)
-#include "net/proxy_resolution/proxy_config_service_ios.h"
 #include "net/proxy_resolution/proxy_resolver_mac.h"
 #elif BUILDFLAG(IS_MAC)
-#include "net/proxy_resolution/proxy_config_service_mac.h"
 #include "net/proxy_resolution/proxy_resolver_mac.h"
-#elif BUILDFLAG(IS_LINUX)
-#include "net/proxy_resolution/proxy_config_service_linux.h"
-#elif BUILDFLAG(IS_ANDROID)
-#include "net/proxy_resolution/proxy_config_service_android.h"
 #endif
 
 using base::TimeTicks;
@@ -65,35 +58,6 @@
 
 namespace {
 
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX)
-constexpr net::NetworkTrafficAnnotationTag kSystemProxyConfigTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("proxy_config_system", R"(
-      semantics {
-        sender: "Proxy Config"
-        description:
-          "Establishing a connection through a proxy server using system proxy "
-          "settings."
-        trigger:
-          "Whenever a network request is made when the system proxy settings "
-          "are used, and they indicate to use a proxy server."
-        data:
-          "Proxy configuration."
-        destination: OTHER
-        destination_other:
-          "The proxy server specified in the configuration."
-      }
-      policy {
-        cookies_allowed: NO
-        setting:
-          "User cannot override system proxy settings, but can change them "
-          "through 'Advanced/System/Open proxy settings'."
-        policy_exception_justification:
-          "Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' "
-          "policies can set Chrome to use a specific proxy settings and avoid "
-          "system proxy."
-      })");
-#endif
-
 const size_t kDefaultNumPacThreads = 4;
 
 // When the IP address changes we don't immediately re-run proxy auto-config.
@@ -354,21 +318,6 @@
   return dict;
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-class UnsetProxyConfigService : public ProxyConfigService {
- public:
-  UnsetProxyConfigService() = default;
-  ~UnsetProxyConfigService() override = default;
-
-  void AddObserver(Observer* observer) override {}
-  void RemoveObserver(Observer* observer) override {}
-  ConfigAvailability GetLatestProxyConfig(
-      ProxyConfigWithAnnotation* config) override {
-    return CONFIG_UNSET;
-  }
-};
-#endif
-
 // Returns a sanitized copy of |url| which is safe to pass on to a PAC script.
 //
 // PAC scripts are modelled as being controllable by a network-present
@@ -1399,55 +1348,6 @@
 }
 
 // static
-std::unique_ptr<ProxyConfigService>
-ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
-    const scoped_refptr<base::SequencedTaskRunner>& main_task_runner) {
-#if BUILDFLAG(IS_WIN)
-  return std::make_unique<ProxyConfigServiceWin>(
-      kSystemProxyConfigTrafficAnnotation);
-#elif BUILDFLAG(IS_IOS)
-  return std::make_unique<ProxyConfigServiceIOS>(
-      kSystemProxyConfigTrafficAnnotation);
-#elif BUILDFLAG(IS_MAC)
-  return std::make_unique<ProxyConfigServiceMac>(
-      main_task_runner, kSystemProxyConfigTrafficAnnotation);
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
-  LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in "
-             << "profile_io_data.cc::CreateProxyConfigService and this should "
-             << "be used only for examples.";
-  return std::make_unique<UnsetProxyConfigService>();
-#elif BUILDFLAG(IS_LINUX)
-  auto linux_config_service = std::make_unique<ProxyConfigServiceLinux>();
-
-  // Assume we got called on the thread that runs the default glib
-  // main loop, so the current thread is where we should be running
-  // gsettings calls from.
-  scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner =
-      base::ThreadTaskRunnerHandle::Get();
-
-  // Synchronously fetch the current proxy config (since we are running on
-  // glib_default_loop). Additionally register for notifications (delivered in
-  // either |glib_default_loop| or an internal sequenced task runner) to
-  // keep us updated when the proxy config changes.
-  linux_config_service->SetupAndFetchInitialConfig(
-      glib_thread_task_runner, main_task_runner,
-      kSystemProxyConfigTrafficAnnotation);
-
-  return std::move(linux_config_service);
-#elif BUILDFLAG(IS_ANDROID)
-  return std::make_unique<ProxyConfigServiceAndroid>(
-      main_task_runner, base::ThreadTaskRunnerHandle::Get());
-#elif BUILDFLAG(IS_FUCHSIA)
-  // TODO(crbug.com/889195): Implement a system proxy service for Fuchsia.
-  return std::make_unique<ProxyConfigServiceDirect>();
-#else
-  LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
-                  "for this platform.";
-  return std::make_unique<ProxyConfigServiceDirect>();
-#endif
-}
-
-// static
 const ConfiguredProxyResolutionService::PacPollPolicy*
 ConfiguredProxyResolutionService::set_pac_script_poll_policy(
     const PacPollPolicy* policy) {
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.h b/net/proxy_resolution/configured_proxy_resolution_service.h
index ede6f58..7ce9e47 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service.h
+++ b/net/proxy_resolution/configured_proxy_resolution_service.h
@@ -34,7 +34,6 @@
 #include "url/gurl.h"
 
 namespace base {
-class SequencedTaskRunner;
 class TimeDelta;
 }  // namespace base
 
@@ -228,16 +227,6 @@
       const std::string& pac_string,
       const NetworkTrafficAnnotationTag& traffic_annotation);
 
-  // Creates a config service appropriate for this platform that fetches the
-  // system proxy settings. |main_task_runner| is the thread where the consumer
-  // of the ProxyConfigService will live.
-  //
-  // TODO(mmenke): Should this be a member of ProxyConfigService?
-  // The ConfiguredProxyResolutionService may not even be in the same process as
-  // the system ProxyConfigService.
-  static std::unique_ptr<ProxyConfigService> CreateSystemProxyConfigService(
-      const scoped_refptr<base::SequencedTaskRunner>& main_task_runner);
-
   // This method should only be used by unit tests.
   void set_stall_proxy_auto_config_delay(base::TimeDelta delay) {
     stall_proxy_auto_config_delay_ = delay;
diff --git a/net/proxy_resolution/proxy_config_service.cc b/net/proxy_resolution/proxy_config_service.cc
new file mode 100644
index 0000000..25d8a321
--- /dev/null
+++ b/net/proxy_resolution/proxy_config_service.cc
@@ -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.
+
+#include "net/proxy_resolution/proxy_config_service.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "net/proxy_resolution/win/proxy_config_service_win.h"
+#elif BUILDFLAG(IS_IOS)
+#include "net/proxy_resolution/proxy_config_service_ios.h"
+#elif BUILDFLAG(IS_MAC)
+#include "net/proxy_resolution/proxy_config_service_mac.h"
+#elif BUILDFLAG(IS_LINUX)
+#include "net/proxy_resolution/proxy_config_service_linux.h"
+#elif BUILDFLAG(IS_ANDROID)
+#include "net/proxy_resolution/proxy_config_service_android.h"
+#endif
+
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX)
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#endif
+
+namespace net {
+
+namespace {
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX)
+constexpr net::NetworkTrafficAnnotationTag kSystemProxyConfigTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("proxy_config_system", R"(
+      semantics {
+        sender: "Proxy Config"
+        description:
+          "Establishing a connection through a proxy server using system proxy "
+          "settings."
+        trigger:
+          "Whenever a network request is made when the system proxy settings "
+          "are used, and they indicate to use a proxy server."
+        data:
+          "Proxy configuration."
+        destination: OTHER
+        destination_other:
+          "The proxy server specified in the configuration."
+      }
+      policy {
+        cookies_allowed: NO
+        setting:
+          "User cannot override system proxy settings, but can change them "
+          "through 'Advanced/System/Open proxy settings'."
+        policy_exception_justification:
+          "Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' "
+          "policies can set Chrome to use a specific proxy settings and avoid "
+          "system proxy."
+      })");
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+class UnsetProxyConfigService : public ProxyConfigService {
+ public:
+  UnsetProxyConfigService() = default;
+  ~UnsetProxyConfigService() override = default;
+
+  void AddObserver(Observer* observer) override {}
+  void RemoveObserver(Observer* observer) override {}
+  ConfigAvailability GetLatestProxyConfig(
+      ProxyConfigWithAnnotation* config) override {
+    return CONFIG_UNSET;
+  }
+};
+#endif
+
+// Config getter that always returns direct settings.
+class ProxyConfigServiceDirect : public ProxyConfigService {
+ public:
+  // ProxyConfigService implementation:
+  void AddObserver(Observer* observer) override {}
+  void RemoveObserver(Observer* observer) override {}
+  ConfigAvailability GetLatestProxyConfig(
+      ProxyConfigWithAnnotation* config) override {
+    *config = ProxyConfigWithAnnotation::CreateDirect();
+    return CONFIG_VALID;
+  }
+};
+
+}  // namespace
+
+// static
+std::unique_ptr<ProxyConfigService>
+ProxyConfigService::CreateSystemProxyConfigService(
+    scoped_refptr<base::SequencedTaskRunner> main_task_runner) {
+#if BUILDFLAG(IS_WIN)
+  return std::make_unique<ProxyConfigServiceWin>(
+      kSystemProxyConfigTrafficAnnotation);
+#elif BUILDFLAG(IS_IOS)
+  return std::make_unique<ProxyConfigServiceIOS>(
+      kSystemProxyConfigTrafficAnnotation);
+#elif BUILDFLAG(IS_MAC)
+  return std::make_unique<ProxyConfigServiceMac>(
+      std::move(main_task_runner), kSystemProxyConfigTrafficAnnotation);
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
+  LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in "
+             << "profile_io_data.cc::CreateProxyConfigService and this should "
+             << "be used only for examples.";
+  return std::make_unique<UnsetProxyConfigService>();
+#elif BUILDFLAG(IS_LINUX)
+  std::unique_ptr<ProxyConfigServiceLinux> linux_config_service(
+      std::make_unique<ProxyConfigServiceLinux>());
+
+  // Assume we got called on the thread that runs the default glib
+  // main loop, so the current thread is where we should be running
+  // gsettings calls from.
+  scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner =
+      base::ThreadTaskRunnerHandle::Get();
+
+  // Synchronously fetch the current proxy config (since we are running on
+  // glib_default_loop). Additionally register for notifications (delivered in
+  // either |glib_default_loop| or an internal sequenced task runner) to
+  // keep us updated when the proxy config changes.
+  linux_config_service->SetupAndFetchInitialConfig(
+      glib_thread_task_runner, std::move(main_task_runner),
+      kSystemProxyConfigTrafficAnnotation);
+
+  return std::move(linux_config_service);
+#elif BUILDFLAG(IS_ANDROID)
+  return std::make_unique<ProxyConfigServiceAndroid>(
+      std::move(main_task_runner), base::ThreadTaskRunnerHandle::Get());
+#elif BUILDFLAG(IS_FUCHSIA)
+  // TODO(crbug.com/889195): Implement a system proxy service for Fuchsia.
+  return std::make_unique<ProxyConfigServiceDirect>();
+#else
+  LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
+                  "for this platform.";
+  return std::make_unique<ProxyConfigServiceDirect>();
+#endif
+}
+
+}  // namespace net
diff --git a/net/proxy_resolution/proxy_config_service.h b/net/proxy_resolution/proxy_config_service.h
index 5ec95b16..9c827378 100644
--- a/net/proxy_resolution/proxy_config_service.h
+++ b/net/proxy_resolution/proxy_config_service.h
@@ -5,8 +5,15 @@
 #ifndef NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_H_
 #define NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_H_
 
+#include <memory>
+
+#include "base/memory/ref_counted.h"
 #include "net/base/net_export.h"
 
+namespace base {
+class SequencedTaskRunner;
+}  // namespace base
+
 namespace net {
 
 class ProxyConfigWithAnnotation;
@@ -62,6 +69,12 @@
   // X seconds at which point they check for changes. However that has
   // the disadvantage of doing continuous work even during idle periods.
   virtual void OnLazyPoll() {}
+
+  // Creates a config service appropriate for this platform that fetches the
+  // system proxy settings. |main_task_runner| is the sequence where the
+  // consumer of the ProxyConfigService will live.
+  static std::unique_ptr<ProxyConfigService> CreateSystemProxyConfigService(
+      scoped_refptr<base::SequencedTaskRunner> main_task_runner);
 };
 
 }  // namespace net
diff --git a/net/tools/net_watcher/net_watcher.cc b/net/tools/net_watcher/net_watcher.cc
index 733aa14..00fbd79 100644
--- a/net/tools/net_watcher/net_watcher.cc
+++ b/net/tools/net_watcher/net_watcher.cc
@@ -28,9 +28,9 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "net/base/network_change_notifier.h"
-#include "net/proxy_resolution/configured_proxy_resolution_service.h"
 #include "net/proxy_resolution/proxy_config.h"
 #include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
 
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
@@ -189,7 +189,7 @@
 
   // Use the network loop as the file loop also.
   std::unique_ptr<net::ProxyConfigService> proxy_config_service(
-      net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
+      net::ProxyConfigService::CreateSystemProxyConfigService(
           io_task_executor.task_runner()));
 
   // Uses |network_change_notifier|.
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index f71e06f4..52c4446 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -505,11 +505,11 @@
   if (!proxy_resolution_service_) {
 #if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
     // TODO(willchan): Switch to using this code when
-    // ConfiguredProxyResolutionService::CreateSystemProxyConfigService()'s
+    // ProxyConfigService::CreateSystemProxyConfigService()'s
     // signature doesn't suck.
     if (!proxy_config_service_) {
       proxy_config_service_ =
-          ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
+          ProxyConfigService::CreateSystemProxyConfigService(
               base::ThreadTaskRunnerHandle::Get().get());
     }
 #endif  // !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) &&
diff --git a/remoting/base/url_request_context_getter.cc b/remoting/base/url_request_context_getter.cc
index c14aafa..b2105fb 100644
--- a/remoting/base/url_request_context_getter.cc
+++ b/remoting/base/url_request_context_getter.cc
@@ -26,7 +26,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
     : network_task_runner_(network_task_runner),
       proxy_config_service_(
-          net::ConfiguredProxyResolutionService::CreateSystemProxyConfigService(
+          net::ProxyConfigService::CreateSystemProxyConfigService(
               network_task_runner)) {}
 
 net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc
index 9c765b2..6e7ae38 100644
--- a/services/network/cors/cors_url_loader.cc
+++ b/services/network/cors/cors_url_loader.cc
@@ -866,7 +866,7 @@
   if (cache_key.has_value()) {
     memory_cache_->CreateLoaderAndStart(
         network_loader_.BindNewPipeAndPassReceiver(), request_id_, options_,
-        *cache_key, request_,
+        *cache_key, request_, net_log_,
         network_client_receiver_.BindNewPipeAndPassRemote());
     memory_cache_was_used_ = true;
   } else if (sync_network_loader_factory_ &&
diff --git a/services/network/network_service_memory_cache.cc b/services/network/network_service_memory_cache.cc
index 6d166f9..eae66c1 100644
--- a/services/network/network_service_memory_cache.cc
+++ b/services/network/network_service_memory_cache.cc
@@ -248,13 +248,14 @@
     uint32_t options,
     const std::string& cache_key,
     const ResourceRequest& resource_request,
+    const net::NetLogWithSource net_log,
     mojo::PendingRemote<mojom::URLLoaderClient> client) {
   auto it = entries_.Get(cache_key);
   CHECK(it != entries_.end());
 
   auto loader = std::make_unique<NetworkServiceMemoryCacheURLLoader>(
-      this, GetNextTraceId(), resource_request.url, std::move(receiver),
-      std::move(client), it->second->content);
+      this, GetNextTraceId(), resource_request.url, net_log,
+      std::move(receiver), std::move(client), it->second->content);
   NetworkServiceMemoryCacheURLLoader* raw_loader = loader.get();
   url_loaders_.insert(std::move(loader));
 
diff --git a/services/network/network_service_memory_cache.h b/services/network/network_service_memory_cache.h
index 19b9d720..968edff 100644
--- a/services/network/network_service_memory_cache.h
+++ b/services/network/network_service_memory_cache.h
@@ -23,6 +23,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
+class NetLogWithSource;
 class NetworkIsolationKey;
 class URLRequest;
 }  // namespace net
@@ -81,6 +82,7 @@
                             uint32_t options,
                             const std::string& cache_key,
                             const ResourceRequest& resource_request,
+                            const net::NetLogWithSource net_log,
                             mojo::PendingRemote<mojom::URLLoaderClient> client);
 
   // Returns a suitable capacity for a data pipe that is used to serve a
diff --git a/services/network/network_service_memory_cache_url_loader.cc b/services/network/network_service_memory_cache_url_loader.cc
index e9f6fb20..9ea06bd 100644
--- a/services/network/network_service_memory_cache_url_loader.cc
+++ b/services/network/network_service_memory_cache_url_loader.cc
@@ -4,8 +4,10 @@
 
 #include "services/network/network_service_memory_cache_url_loader.h"
 
+#include "base/bit_cast.h"
 #include "base/trace_event/common/trace_event_common.h"
 #include "base/trace_event/trace_event.h"
+#include "net/http/http_log_util.h"
 #include "services/network/network_service_memory_cache.h"
 #include "services/network/public/cpp/resource_request.h"
 
@@ -15,11 +17,13 @@
     NetworkServiceMemoryCache* memory_cache,
     uint64_t trace_id,
     const GURL& url,
+    const net::NetLogWithSource& net_log,
     mojo::PendingReceiver<mojom::URLLoader> receiver,
     mojo::PendingRemote<mojom::URLLoaderClient> client,
     scoped_refptr<base::RefCountedBytes> content)
     : memory_cache_(memory_cache),
       trace_id_(trace_id),
+      net_log_(net_log),
       receiver_(this, std::move(receiver)),
       client_(std::move(client)),
       content_(std::move(content)) {
@@ -59,6 +63,10 @@
     return;
   }
 
+  net::NetLogResponseHeaders(
+      net_log_, net::NetLogEventType::IN_MEMORY_CACHE_READ_RESPONSE_HEADERS,
+      response_head->headers.get());
+
   // Start sending the response.
   client_->OnReceiveResponse(std::move(response_head),
                              std::move(consumer_handle));
@@ -104,6 +112,7 @@
 }
 
 void NetworkServiceMemoryCacheURLLoader::WriteMore() {
+  size_t original_write_position = write_position_;
   size_t total_write_size = 0;
   bool write_completed = false;
   while (true) {
@@ -139,6 +148,13 @@
       TRACE_ID_LOCAL(trace_id_), "write_position", write_position_,
       "total_write_bytes", total_write_size);
 
+  if (net_log_.IsCapturing()) {
+    net_log_.AddByteTransferEvent(
+        net::NetLogEventType::IN_MEMORY_CACHE_BYTES_READ, total_write_size,
+        base::bit_cast<const char*>(content_->data().data() +
+                                    original_write_position));
+  }
+
   if (write_completed) {
     Finish(net::OK);
   }
diff --git a/services/network/network_service_memory_cache_url_loader.h b/services/network/network_service_memory_cache_url_loader.h
index 5749941..45befc06 100644
--- a/services/network/network_service_memory_cache_url_loader.h
+++ b/services/network/network_service_memory_cache_url_loader.h
@@ -18,6 +18,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
+#include "net/log/net_log_with_source.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -36,6 +37,7 @@
       NetworkServiceMemoryCache* memory_cache,
       uint64_t trace_id,
       const GURL& url,
+      const net::NetLogWithSource& net_log,
       mojo::PendingReceiver<mojom::URLLoader> receiver,
       mojo::PendingRemote<mojom::URLLoaderClient> client,
       scoped_refptr<base::RefCountedBytes> content);
@@ -82,6 +84,8 @@
   // For tracing.
   const uint64_t trace_id_;
 
+  const net::NetLogWithSource net_log_;
+
   mojo::Receiver<mojom::URLLoader> receiver_;
   mojo::Remote<mojom::URLLoaderClient> client_;
 
diff --git a/styleguide/c++/c++-features.md b/styleguide/c++/c++-features.md
index fa8063c..80659bb 100644
--- a/styleguide/c++/c++-features.md
+++ b/styleguide/c++/c++-features.md
@@ -424,6 +424,26 @@
 [Google Style Guide](https://google.github.io/styleguide/cppguide.html#CTAD).
 ***
 
+### Fold expressions <sup>[allowed]</sup>
+
+```c++
+template <typename... Args>
+auto sum(Args... args) {
+  return (... + args);
+}
+```
+
+**Description:** A fold expression performs a fold of a template parameter pack
+over a binary operator.
+
+**Documentation:**
+[Fold expression](https://en.cppreference.com/w/cpp/language/fold)
+
+**Notes:**
+*** promo
+[Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/4DTm3idXz0w/m/g_JjOh0wAgAJ)
+***
+
 ### Selection statements with initializer <sup>[allowed]</sup>
 
 ```c++
@@ -973,26 +993,6 @@
 None
 ***
 
-### Fold expressions <sup>[tbd]</sup>
-
-```c++
-template <typename... Args>
-auto sum(Args... args) {
-  return (... + args);
-}
-```
-
-**Description:** A fold expression performs a fold of a template parameter pack
-over a binary operator.
-
-**Documentation:**
-[Fold expression](https://en.cppreference.com/w/cpp/language/fold)
-
-**Notes:**
-*** promo
-None
-***
-
 ### constexpr lambda <sup>[tbd]</sup>
 
 ```c++
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 8b6ae59..0fb45d5 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -8333,15 +8333,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8367,7 +8367,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8418,15 +8418,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8452,7 +8452,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8843,15 +8843,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M103/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8877,7 +8877,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -8928,15 +8928,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M104/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -8962,7 +8962,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 5df286d..a7304bf 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -2831,7 +2831,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -6363,7 +6364,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 20
+          "shards": 19
         },
         "test": "chrome_public_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
@@ -6420,7 +6421,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -21026,7 +21028,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -37448,7 +37451,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -40557,7 +40561,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 20
+          "shards": 19
         },
         "test": "chrome_public_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
@@ -40614,7 +40618,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -46508,15 +46513,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46542,7 +46547,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -46593,15 +46598,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -46627,7 +46632,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47018,15 +47023,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M103/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47052,7 +47057,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47103,15 +47108,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M104/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47137,7 +47142,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47532,15 +47537,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47566,7 +47571,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -47617,15 +47622,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -47651,7 +47656,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48042,15 +48047,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M103/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48076,7 +48081,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48127,15 +48132,15 @@
       {
         "args": [
           "--additional-apk=apks/ChromePublic.apk",
+          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/AOSP_SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M104/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48161,7 +48166,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48624,15 +48629,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48658,7 +48663,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -48709,15 +48714,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -48743,7 +48748,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49134,15 +49139,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M103/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49168,7 +49173,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49219,15 +49224,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M104/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49253,7 +49258,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49716,15 +49721,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M103/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M103/out/Release",
           "--client-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49750,7 +49755,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49801,15 +49806,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M104/out/Release",
           "--implementation-outdir",
           ".",
           "--test-expectations",
           "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
-          "--client-outdir",
-          "../../weblayer_instrumentation_test_M104/out/Release",
           "--client-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -49835,7 +49840,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50226,15 +50231,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M103/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=103",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -50260,7 +50265,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M103",
-              "revision": "version:103.0.5060.119"
+              "revision": "version:103.0.5060.120"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50311,15 +50316,15 @@
       {
         "args": [
           "--additional-apk=apks/WebLayerShellSystemWebView.apk",
+          "--webview-apk-path=apks/SystemWebView.apk",
           "--test-runner-outdir",
           ".",
           "--client-outdir",
           ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--webview-apk-path=apks/SystemWebView.apk",
           "--implementation-outdir",
           "../../weblayer_instrumentation_test_M104/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
           "--impl-version=104",
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
@@ -50345,7 +50350,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M104",
-              "revision": "version:104.0.5112.39"
+              "revision": "version:104.0.5112.40"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 2996d506..2e73453 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5592,21 +5592,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -5619,26 +5619,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -5651,7 +5651,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -5688,21 +5688,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -5715,7 +5715,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
@@ -5760,21 +5760,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -5786,26 +5786,26 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -5817,7 +5817,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -5853,21 +5853,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -5879,7 +5879,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "args": [
@@ -5906,21 +5906,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -5932,26 +5932,26 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -5963,7 +5963,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -5999,21 +5999,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -6025,7 +6025,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index cf9a738..6509d90 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -5883,7 +5883,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 20
+          "shards": 19
         },
         "test": "chrome_public_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
@@ -5939,7 +5939,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9966d643..00d5ede 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -11172,7 +11172,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 20
+          "shards": 19
         },
         "test": "chrome_public_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
@@ -11283,7 +11283,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -15141,7 +15142,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -92824,21 +92826,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -92846,26 +92848,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -92873,7 +92875,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -92905,21 +92907,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -92927,7 +92929,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
@@ -92962,54 +92964,54 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -93040,28 +93042,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "args": [
@@ -93083,54 +93085,54 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -93161,28 +93163,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
@@ -94424,20 +94426,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -94451,25 +94453,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -94483,7 +94485,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -94520,20 +94522,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -94547,7 +94549,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "merge": {
@@ -94592,20 +94594,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -94618,25 +94620,25 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -94649,7 +94651,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -94685,20 +94687,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -94711,7 +94713,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "args": [
@@ -94738,20 +94740,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -94764,25 +94766,25 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -94795,7 +94797,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -94831,20 +94833,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -94857,7 +94859,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "merge": {
@@ -96257,20 +96259,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -96284,25 +96286,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -96316,7 +96318,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -96353,20 +96355,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -96380,7 +96382,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "merge": {
@@ -96425,20 +96427,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -96451,25 +96453,25 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -96482,7 +96484,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -96518,20 +96520,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -96544,7 +96546,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "args": [
@@ -96571,20 +96573,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -96597,25 +96599,25 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -96628,7 +96630,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -96664,20 +96666,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -96690,7 +96692,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "merge": {
@@ -97332,20 +97334,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -97358,25 +97360,25 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -97389,7 +97391,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -97425,20 +97427,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -97451,7 +97453,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 597bf201..5e7c4b61 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -15350,7 +15350,8 @@
               "name": "shard #${SHARD_INDEX} logcats"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 2
         },
         "test": "chrome_public_unit_test_apk",
         "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/"
@@ -20778,21 +20779,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.64",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -20805,26 +20806,26 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.23",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -20837,7 +20838,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -20874,21 +20875,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5166.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -20901,7 +20902,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
@@ -20946,21 +20947,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -20972,26 +20973,26 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -21003,7 +21004,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -21039,21 +21040,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -21065,7 +21066,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "args": [
@@ -21092,21 +21093,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.64",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5060.114",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5060.64",
-              "revision": "version:103.0.5060.64"
+              "location": "lacros_version_skew_tests_v103.0.5060.114",
+              "revision": "version:103.0.5060.114"
             }
           ],
           "dimension_sets": [
@@ -21118,26 +21119,26 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 103.0.5060.64"
+        "variant_id": "Lacros version skew testing ash 103.0.5060.114"
       },
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.23",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5112.36",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5112.23",
-              "revision": "version:104.0.5112.23"
+              "location": "lacros_version_skew_tests_v104.0.5112.36",
+              "revision": "version:104.0.5112.36"
             }
           ],
           "dimension_sets": [
@@ -21149,7 +21150,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5112.23"
+        "variant_id": "Lacros version skew testing ash 104.0.5112.36"
       },
       {
         "args": [
@@ -21185,21 +21186,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5166.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 105.0.5167.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v105.0.5166.0",
-              "revision": "version:105.0.5166.0"
+              "location": "lacros_version_skew_tests_v105.0.5167.0",
+              "revision": "version:105.0.5167.0"
             }
           ],
           "dimension_sets": [
@@ -21211,7 +21212,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 105.0.5166.0"
+        "variant_id": "Lacros version skew testing ash 105.0.5167.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index a1e13a7..c992d7c 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -534,13 +534,16 @@
     'chrome_public_tests': {
       'chrome_public_test_apk': {
         'swarming': {
-          'shards': 20,
+          'shards': 19,
         },
         'mixins': [
           'skia_gold_test',
         ],
       },
       'chrome_public_unit_test_apk': {
+        'swarming': {
+          'shards': 2,
+        },
         'mixins': [
           'skia_gold_test',
         ],
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 49ab912..862dcbe 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5166.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v105.0.5167.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 105.0.5166.0',
+    'identifier': 'Lacros version skew testing ash 105.0.5167.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v105.0.5166.0',
-          'revision': 'version:105.0.5166.0',
+          'location': 'lacros_version_skew_tests_v105.0.5167.0',
+          'revision': 'version:105.0.5167.0',
         },
       ],
     },
@@ -52,30 +52,30 @@
   },
   'LACROS_VERSION_SKEW_BETA': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.23/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5112.36/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 104.0.5112.23',
+    'identifier': 'Lacros version skew testing ash 104.0.5112.36',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v104.0.5112.23',
-          'revision': 'version:104.0.5112.23',
+          'location': 'lacros_version_skew_tests_v104.0.5112.36',
+          'revision': 'version:104.0.5112.36',
         },
       ],
     },
   },
   'LACROS_VERSION_SKEW_STABLE': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.64/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5060.114/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 103.0.5060.64',
+    'identifier': 'Lacros version skew testing ash 103.0.5060.114',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v103.0.5060.64',
-          'revision': 'version:103.0.5060.64',
+          'location': 'lacros_version_skew_tests_v103.0.5060.114',
+          'revision': 'version:103.0.5060.114',
         },
       ],
     },
@@ -529,16 +529,16 @@
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M104/out/Release',
-      '--impl-version=104'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=104',
     ],
     'identifier': 'with_impl_from_104',
     'swarming': {
@@ -546,23 +546,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.39'
+          'revision': 'version:104.0.5112.40',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/AOSP_SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M103/out/Release',
-      '--impl-version=103'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=103',
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -570,10 +570,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.119'
+          'revision': 'version:103.0.5060.120',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -673,16 +673,16 @@
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M104/out/Release',
-      '--impl-version=104'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=104',
     ],
     'identifier': 'with_impl_from_104',
     'swarming': {
@@ -690,23 +690,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.39'
+          'revision': 'version:104.0.5112.40',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
       '--client-outdir',
       '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
       '--implementation-outdir',
       '../../weblayer_instrumentation_test_M103/out/Release',
-      '--impl-version=103'
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=103',
     ],
     'identifier': 'with_impl_from_103',
     'swarming': {
@@ -714,10 +714,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.119'
+          'revision': 'version:103.0.5060.120',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
@@ -817,16 +817,16 @@
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M104/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M104/out/Release',
-      '--client-version=104'
+      '--client-version=104',
     ],
     'identifier': 'with_client_from_104',
     'swarming': {
@@ -834,23 +834,23 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M104',
-          'revision': 'version:104.0.5112.39'
+          'revision': 'version:104.0.5112.40',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
+      '--webview-apk-path=apks/SystemWebView.apk',
       '--test-runner-outdir',
       '.',
+      '--client-outdir',
+      '../../weblayer_instrumentation_test_M103/out/Release',
       '--implementation-outdir',
       '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--webview-apk-path=apks/SystemWebView.apk',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M103/out/Release',
-      '--client-version=103'
+      '--client-version=103',
     ],
     'identifier': 'with_client_from_103',
     'swarming': {
@@ -858,10 +858,10 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M103',
-          'revision': 'version:103.0.5060.119'
+          'revision': 'version:103.0.5060.120',
         }
-      ]
-    }
+      ],
+    },
   },
   'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index ae3604e..2e79626 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4424,6 +4424,52 @@
             ]
         }
     ],
+    "HappinessTrackingSurveysForDesktopPrivacyGuide": [
+        {
+            "platforms": [
+                "linux",
+                "windows",
+                "mac"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "en_site_id": "EwTBYAUeU0ugnJ3q1cK0VNYBFfQr",
+                        "probability": "1.0",
+                        "settings-time": "5s",
+                        "survey": "privacy-guide"
+                    },
+                    "enable_features": [
+                        "HappinessTrackingSurveysForDesktopPrivacyGuide"
+                    ]
+                }
+            ]
+        }
+    ],
+    "HappinessTrackingSurveysForDesktopSettingsPrivacy": [
+        {
+            "platforms": [
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "en_site_id": "JcjxgSDnh0ugnJ3q1cK0UVkwDj1o",
+                        "no-guide": "true",
+                        "probability": "1.0",
+                        "survey": "settings-privacy"
+                    },
+                    "enable_features": [
+                        "HappinessTrackingSurveysForDesktopSettingsPrivacy"
+                    ]
+                }
+            ]
+        }
+    ],
     "HappinessTrackingSystemPerformance": [
         {
             "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index cd5b469..01dbdaa 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -81,10 +81,9 @@
 
 // Enable eagerly setting up a CacheStorage interface pointer and
 // passing it to service workers on startup as an optimization.
-// TODO(crbug/1077916): Re-enable once the issue with COOP/COEP is fixed.
 const base::Feature kEagerCacheStorageSetupForServiceWorkers{
     "EagerCacheStorageSetupForServiceWorkers",
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Controls script streaming.
 const base::Feature kScriptStreaming{"ScriptStreaming",
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping.cc b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
index 9ec33dfe..74a1324 100644
--- a/third_party/blink/renderer/core/editing/text_offset_mapping.cc
+++ b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
@@ -195,6 +195,14 @@
       break;
     }
     if (layout_object->IsBlockInInline()) {
+      if (target.IsDescendantOf(layout_object)) {
+        // Note: We reach here when `target` is `position:absolute` or
+        // `position:fixed`, aka `IsOutOfFlowPositioned()`, because
+        // `LayoutObject::ContainingBlock()` handles them specially.
+        // See http://crbug.com/1324970
+        last = first;
+        break;
+      }
       block_in_inline_before = layout_object;
       first = last = nullptr;
     }
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
index d305e12..0fe59b4 100644
--- a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/editing/text_offset_mapping.h"
 
+#include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/blink/renderer/core/editing/position.h"
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
@@ -18,6 +19,8 @@
 
 namespace blink {
 
+using ::testing::ElementsAre;
+
 class ParameterizedTextOffsetMappingTest
     : public ::testing::WithParamInterface<bool>,
       private ScopedLayoutNGForTest,
@@ -285,6 +288,28 @@
   EXPECT_TRUE(previous_contents.IsNull());
 }
 
+// http://crbug.com/1324970
+TEST_P(ParameterizedTextOffsetMappingTest, BlockInInlineWithAbsolute) {
+  InsertStyleElement("a { position:absolute; } #t { position: relative; }");
+  const PositionInFlatTree position = ToPositionInFlatTree(
+      SetCaretTextToBody("<div id=t><i><p><a></a></p></i> </div><p>|ab</p>"));
+
+  Vector<String> results;
+  for (const auto contents : TextOffsetMapping::BackwardRangeOf(position))
+    results.push_back(GetRange(contents));
+
+  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+    ElementsAre("<div id=\"t\"><i><p><a></a></p></i> </div><p>^ab|</p>",
+                "<div id=\"t\"><i><p><a></a></p></i>^ |</div><p>ab</p>",
+                "<div id=\"t\">^<i><p><a></a></p></i>| </div><p>ab</p>");
+  } else {
+    EXPECT_THAT(
+        results,
+        ElementsAre("<div id=\"t\"><i><p><a></a></p></i> </div><p>^ab|</p>",
+                    "<div id=\"t\">^<i><p><a></a></p></i> |</div><p>ab</p>"));
+  }
+}
+
 TEST_P(ParameterizedTextOffsetMappingTest, ForwardRangesWithTextControl) {
   // InlineContents for positions outside text control should cover the entire
   // containing block.
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 4c887ca..fe56c51 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -857,11 +857,7 @@
       default_allow_deferred_shaping_ =
           default_allow_deferred_shaping_ &&
           RuntimeEnabledFeatures::DeferredShapingEnabled() &&
-          !frame_->PagePopupOwner() &&
-          // Avoid a DCEHCK failure in |NavigatingExtensionPopupInteractiveTest.
-          // PageInOtherExtension_Get| on linux-lacros-rel.
-          // TODO(tkent): Investigate the failure.
-          !document->Url().Protocol().StartsWith("chrome-error") &&
+          !frame_->PagePopupOwner() && !auto_size_info_ &&
           !FirstMeaningfulPaintDetector::From(*frame_->GetDocument())
                .SeenFirstMeaningfulPaint();
       base::AutoReset<bool> deferred_shaping(
diff --git a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
index 6ee13518..b22bf59 100644
--- a/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
+++ b/third_party/blink/renderer/core/layout/deferred_shaping_test.cc
@@ -797,4 +797,20 @@
   EXPECT_FALSE(IsLocked("target"));
 }
 
+TEST_F(DeferredShapingTest, NoDeferForAutoSizing) {
+  GetDocument().body()->setInnerHTML(R"HTML(
+    <style>
+    @media (max-height: 200px) {
+      #target { display: inline; }
+    }
+    </style>
+    <div style="height:1800px"></div>
+    <div id="target">IFC</div>)HTML",
+                                     ASSERT_NO_EXCEPTION);
+
+  GetFrame().View()->EnableAutoSizeMode({100, 100}, {1920, 4000});
+  UpdateAllLifecyclePhasesForTest();
+  // Pass if no DCHECK failures.
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index 1ce1d56..32e7b04d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -3124,8 +3124,12 @@
     container_builder_.AddResult(*result, offset);
     return;
   }
-  // Another child should provide the baseline.
-  DCHECK(container_builder_.Baseline());
+  // Usually another child provides the baseline. However it doesn't if
+  // another child is out-of-flow.
+  if (!container_builder_.Baseline()) {
+    container_builder_.AddResult(*result, offset);
+    return;
+  }
   NGBoxFragment fragment(ConstraintSpace().GetWritingDirection(),
                          To<NGPhysicalBoxFragment>(result->PhysicalFragment()));
   // We should apply FirstBaseline() of the placeholder fragment because the
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
index 3916f83..5a107b68 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -2480,14 +2480,18 @@
 }
 
 TEST_F(NGBlockLayoutAlgorithmTest, HandleTextControlPlaceholderCrash) {
-  // crbug.com/1209025. This test passes if no crash.
+  // crbug.com/1209025 and crbug.com/1342608. This test passes if no crash.
   SetBodyInnerHTML(R"HTML(
 <style>
 input::first-line {
  color: red;
 }
+#num::-webkit-textfield-decoration-container {
+ position: absolute;
+}
 </style>
-<input id="i1" readonly>)HTML");
+<input id="i1" readonly>
+<input id="num" type="number" placeholder="foo">)HTML");
   UpdateAllLifecyclePhasesForTest();
   auto* input = GetDocument().getElementById("i1");
   input->setAttribute(html_names::kPlaceholderAttr, "z");
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 262c6d9..0628f5f2 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -408,17 +408,37 @@
 crbug.com/730267 [ Mac11 ] virtual/gpu-rasterization/images/yuv-decode-eligible/webp-no-color-profile-lossy.html [ Failure Pass Timeout ]
 crbug.com/730267 [ Mac12 ] virtual/gpu-rasterization/images/yuv-decode-eligible/webp-no-color-profile-lossy.html [ Failure Pass Timeout ]
 
-# Flaky virtual/threaded/fast/scrolling tests
+# Flaky virtual/threaded-prefer-compositing tests
+crbug.com/1309533 [ Win ] virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness.html [ Failure ]
+crbug.com/1180479 [ Mac ] virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/scrollIntoView-smooth.html [ Failure Pass Timeout ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-scroll-animates.html [ Skip ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-scroll-root-frame-animates.html [ Skip ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Skip ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/main-thread-scrolling-reason-added.html [ Skip ]
+crbug.com/574283 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/main-thread-scrolling-reason-correctness.html [ Skip ]
+crbug.com/574283 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-interrupted.html [ Skip ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html [ Skip ]
+crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-vertical-rl-anchors.html [ Skip ]
+crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/animate-fling-to-snap-points-2.html [ Failure Pass Timeout ]
+crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snap-scrolls-visual-viewport.html [ Failure Pass ]
+crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-scrollbar-scrolling-thumb.html [ Failure Pass ]
+crbug.com/1205673 [ Linux ] virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-wheel-scrolling-single-tick.html [ Failure Pass ]
+crbug.com/1205673 [ Win ] virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-wheel-scrolling-single-tick.html [ Failure Pass ]
+crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-wheel-scrolling.html [ Failure Pass ]
+crbug.com/936891 virtual/threaded-prefer-compositing/fast/scrolling/document-level-touchmove-event-listener-passive-by-default.html [ Pass ]
+crbug.com/1049599 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html [ Failure Pass Skip Timeout ]
+crbug.com/1193920 virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html [ Failure Pass Timeout ]
+crbug.com/1335172 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html [ Failure Pass ]
+crbug.com/1335172 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html [ Failure Pass ]
 crbug.com/841567 [ Debug Mac11 ] virtual/threaded-prefer-compositing/fast/scrolling/listbox-wheel-event.html [ Failure Pass Timeout ]
 crbug.com/841567 [ Debug Mac12 ] virtual/threaded-prefer-compositing/fast/scrolling/listbox-wheel-event.html [ Failure Pass Timeout ]
-crbug.com/841567 [ Mac10.14 ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
-crbug.com/841567 [ Mac10.15 ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
-crbug.com/841567 [ Mac11 ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
-crbug.com/841567 [ Mac12 ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
-crbug.com/841567 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
+crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/overflow-scrollability.html [ Failure Pass Timeout ]
+crbug.com/1095540 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/resize-corner-tracking-touch.html [ Skip ]
 crbug.com/841567 [ Debug Mac11 ] virtual/threaded-prefer-compositing/fast/scrolling/same-page-navigate.html [ Failure Pass ]
-
-crbug.com/1335172 [ Mac11-arm64 ] virtual/threaded-prefer-compositing/fast/scrolling/inertial-scrolling-with-pointer-events-none-overlay.html [ Failure Pass ]
+crbug.com/1279758 [ Win10.20h2 ] virtual/threaded-prefer-compositing/fast/scrolling/scroll-animation-on-by-default.html [ Failure Pass ]
+crbug.com/1279758 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scroll-animation-on-by-default.html [ Failure Pass ]
+crbug.com/1058244 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-rtl-manipulation.html [ Failure Pass ]
+crbug.com/1058244 [ Win ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-rtl-manipulation.html [ Failure Pass ]
 
 crbug.com/915926 fast/events/touch/multi-touch-user-gesture.html [ Failure Pass ]
 
@@ -896,29 +916,108 @@
 
 # Triage of WPT css-paint-api tests
 crbug.com/1299442 external/wpt/css/css-paint-api/custom-property-animation-on-main-thread.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-007.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-shadows.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-with-float-size.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-008.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/roundrect.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-001.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/device-pixel-ratio.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/device-pixel-ratio.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/device-pixel-ratio.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-this-value.https.html [ Failure Pass ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-006.https.html [ Failure ]
-crbug.com/1299442 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-002.https.html [ Failure ]
-crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html [ Failure Pass ]
+
+# Flaky virtual/off-main-thread-css-paint tests
+crbug.com/1254382 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/background-image-alpha.https.html [ Failure ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/background-repeat-x.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/color-custom-property-animation.https.html [ Failure Pass ]
 crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-001.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-001.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-arguments.https.html [ Failure ]
-crbug.com/1299442 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-011.https.html [ Failure ]
+crbug.com/1299442 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-001.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html [ Skip ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-001.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-002.https.html [ Failure Pass ]
+crbug.com/1286944 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-002.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-003.https.html [ Failure Pass ]
+crbug.com/1286944 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-003.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-004.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-005.https.html [ Failure Pass ]
+crbug.com/1286944 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-005.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-with-float-size.https.html [ Failure Pass ]
+crbug.com/1286944 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/canvas-transform.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/device-pixel-ratio.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-constructor-error.https.html [ Failure Pass ]
+crbug.com/1286944 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-constructor-error.https.html [ Failure Pass ]
+crbug.com/1250666 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-paint-error.https.html [ Pass Timeout ]
+crbug.com/1250666 [ Win ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-paint-error.https.html [ Pass Timeout ]
+crbug.com/1250666 crbug.com/1286944 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Failure Pass Timeout ]
+crbug.com/1236558 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/no-op-animation.https.html [ Crash Failure Pass ]
+crbug.com/1287915 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/non-registered-property-value.https.html [ Skip ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/one-custom-property-animation.https.html [ Skip ]
+crbug.com/1286944 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/overdraw.https.html [ Failure Pass Timeout ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-arguments.https.html [ Failure ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-arguments-var.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-arguments.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-this-value.https.html [ Failure Pass ]
+crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-canvasFilter.tentative.https.html [ Failure ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-canvasFilter.tentative.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-conicGradient.https.html [ Failure Pass ]
+crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-filter.https.html [ Failure ]
+crbug.com/1339051 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-filter.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-gradient.https.html [ Failure Pass ]
+crbug.com/1234302 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-image.https.html [ Crash Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-rects.https.html [ Failure Pass ]
+crbug.com/1286944 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-rects.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-shadows.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html [ Skip ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html [ Skip ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-005.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-007.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-008.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html [ Failure Pass ]
+crbug.com/1286944 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html [ Failure Pass ]
+crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html [ Skip ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html [ Skip ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-014.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-015.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-016.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html [ Failure Pass ]
+crbug.com/1242243 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html [ Crash Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-019.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-020.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html [ Skip ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-022.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-001.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-002.https.html [ Skip ]
+crbug.com/1341471 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-003.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-005.https.html [ Skip ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-006.https.html [ Failure ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-007.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-008.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-009.https.html [ Failure Pass ]
+crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-010.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-stylemap.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-001.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-002.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-003.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-004.https.html [ Skip ]
+crbug.com/1288136 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-005.https.html [ Failure Pass ]
 crbug.com/1299442 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-006.https.html [ Failure Pass ]
 crbug.com/1299442 [ Win10.20h2 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-006.https.html [ Failure Pass ]
-crbug.com/1299442 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-007.https.html [ Failure Pass ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-007.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-008.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-009.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-01.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-011.https.html [ Failure Pass ]
+crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-012.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-013.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-014.https.html [ Failure Pass ]
+crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-015.https.html [ Skip ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-016.https.html [ Failure Pass ]
+crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-017.https.html [ Skip ]
+crbug.com/1299442 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/roundrect.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-001.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-002.https.html [ Failure Pass ]
+crbug.com/1299442 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-003.https.html [ Failure Pass ]
+crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-004.https.html [ Failure Pass ]
+crbug.com/1250666 crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-after-load.https.html [ Failure Pass Timeout ]
+crbug.com/1250666 crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-before-load.https.html [ Failure Pass Timeout ]
+crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/http/tests/csspaint/shadow-scale-with-page-zoom.html [ Failure ]
 
 # ====== Paint team owned tests to here ======
 
@@ -2147,7 +2246,6 @@
 
 # Only virtual/threaded version of these tests pass (or running them with --enable-threaded-compositing).
 crbug.com/936891 fast/scrolling/document-level-touchmove-event-listener-passive-by-default.html [ Failure ]
-crbug.com/936891 virtual/threaded-prefer-compositing/fast/scrolling/document-level-touchmove-event-listener-passive-by-default.html [ Pass ]
 
 crbug.com/498539 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Failure Pass ]
 
@@ -2366,8 +2464,6 @@
 crbug.com/1218716 external/wpt/permissions-policy/experimental-features/trust-token-redemption-supported-by-permissions-policy.tentative.html [ Failure ]
 
 # Sheriff 2020-02-06
-# Flaking on Linux Leak
-crbug.com/1049599 [ Linux ] virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html [ Failure Pass Skip Timeout ]
 
 # These are added to W3CImportExpectations as Skip, remove when next import is done.
 crbug.com/666657 external/wpt/css/css-text/hanging-punctuation/* [ Skip ]
@@ -2458,8 +2554,6 @@
 crbug.com/997202 [ Mac ] virtual/text-antialias/international/bdo-bidi-width.html [ Failure ]
 
 crbug.com/574283 [ Mac ] fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html [ Skip ]
-crbug.com/574283 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/main-thread-scrolling-reason-correctness.html [ Skip ]
-crbug.com/574283 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-interrupted.html [ Skip ]
 
 crbug.com/599670 [ Win ] http/tests/devtools/resource-parameters-ipv6.js [ Crash Failure Pass ]
 crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Failure ]
@@ -4220,13 +4314,6 @@
 
 crbug.com/849670 http/tests/devtools/service-workers/service-worker-v8-cache.js [ Failure Pass Timeout ]
 
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-scroll-animates.html [ Skip ]
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-scroll-root-frame-animates.html [ Skip ]
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Skip ]
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/main-thread-scrolling-reason-added.html [ Skip ]
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html [ Skip ]
-crbug.com/664858 virtual/threaded-prefer-compositing/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-vertical-rl-anchors.html [ Skip ]
-
 # ====== Random order flaky tests end here ======
 
 # ====== Tests from enabling .any.js/.worker.js tests begin here ======
@@ -5299,7 +5386,6 @@
 # Sheriff 2020-03-06
 crbug.com/1059262 virtual/threaded/http/tests/worklet/webexposed/global-interface-listing-paint-worklet.html [ Failure Pass ]
 crbug.com/1059262 [ Mac ] webexposed/global-interface-listing-platform-specific.html [ Failure Pass ]
-crbug.com/1058244 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbars/scrollbar-rtl-manipulation.html [ Failure Pass ]
 
 # Sheriff 2020-03-08
 crbug.com/1059645 external/wpt/pointerevents/pointerevent_coalesced_events_attributes.html [ Failure Pass ]
@@ -5639,7 +5725,6 @@
 # Sheriff 2021-02-19
 crbug.com/1180227 [ Mac ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html [ Crash Failure Pass ]
 crbug.com/1180227 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html [ Failure Pass ]
-crbug.com/1180479 [ Mac ] virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/scrollIntoView-smooth.html [ Failure Pass Timeout ]
 
 crbug.com/1180274 crbug.com/1046784 [ Win ] http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
 crbug.com/1180274 crbug.com/1046784 [ Linux ] http/tests/inspector-protocol/network/navigate-iframe-out2in.js [ Failure Pass ]
@@ -5661,14 +5746,6 @@
 
 crbug.com/1185051 fast/canvas/OffscreenCanvas-Bitmaprenderer-toBlob-worker.html [ Failure Pass ]
 
-# Updating virtual suite from virtual/threaded/fast/scroll-snap to
-# virtual/threaded-prefer-compositing/fast/scroll-snap exposes additional
-# tests that fail on the composited code path.
-crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-scrollbar-scrolling-thumb.html [ Failure Pass ]
-crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-wheel-scrolling.html [ Failure Pass ]
-crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/snap-scrolls-visual-viewport.html [ Failure Pass ]
-crbug.com/1186753 virtual/threaded-prefer-compositing/fast/scroll-snap/animate-fling-to-snap-points-2.html [ Failure Pass Timeout ]
-
 # Expect failure for unimplemented canvas color object input
 crbug.com/1187575 external/wpt/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.html [ Failure ]
 crbug.com/1187575 external/wpt/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.transparency.html [ Failure ]
@@ -5817,7 +5894,6 @@
 
 # Sheriff 2021-05-04
 crbug.com/1205659 [ Mac ] external/wpt/IndexedDB/key-generators/reading-autoincrement-indexes.any.worker.html [ Pass Timeout ]
-crbug.com/1205673 [ Linux ] virtual/threaded-prefer-compositing/fast/scroll-snap/snaps-after-wheel-scrolling-single-tick.html [ Failure Pass ]
 
 # Blink_web_tests 2021-05-06
 crbug.com/1205669 [ Mac10.13 ] virtual/threaded/external/wpt/animation-worklet/idlharness.any.worker.html [ Failure ]
@@ -5866,7 +5942,6 @@
 
 # Sheriff 2021-11-15
 crbug.com/1270362 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Failure Pass Timeout ]
-crbug.com/1270362 http/tests/devtools/sources/debugger/debug-inlined-scripts-fragment-id.js [ Failure Pass Timeout ]
 
 # The wpt_flags=h2 variants of these tests fail, but the other variants pass. We
 # can't handle this difference with -expected.txt files, so we have to list them
@@ -6047,10 +6122,6 @@
 # Flaky on Mac11 Tests
 crbug.com/1197464 [ Mac ] plugins/refcount-leaks.html [ Failure Pass ]
 
-# Sheriff 2021-07-01
-# Now also flakily timing-out.
-crbug.com/1193920 virtual/threaded-prefer-compositing/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html [ Failure Pass Timeout ]
-
 # Sheriff 2021-07-05
 crbug.com/1226445 [ Mac ] virtual/storage-access-api/external/wpt/storage-access-api/storageAccess.testdriver.sub.html [ Failure Pass ]
 
@@ -6129,13 +6200,9 @@
 crbug.com/1222097 [ Mac ] external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-sorted-before-dispatch.html [ Failure Pass ]
 crbug.com/1231989 [ Linux ] external/wpt/html/cross-origin-embedder-policy/shared-workers.https.html [ Failure Pass ]
 
-# Sheriff 2021-07-26
-crbug.com/1254382 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/background-image-alpha.https.html [ Failure ]
-
 # Sheriff 2021-07-28
 crbug.com/1233781 http/tests/serviceworker/window-close-during-registration.html [ Failure Pass ]
 crbug.com/1234057 external/wpt/css/css-paint-api/no-op-animation.https.html [ Failure Pass ]
-crbug.com/1234302 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-image.https.html [ Crash Failure Pass ]
 
 # Temporarily disabling progress based worklet animation tests.
 crbug.com/1238130 animations/animationworklet/playback-rate-scroll-timeline-accelerated-property.html [ Timeout ]
@@ -6176,7 +6243,6 @@
 
 # Sheriff 2021-08-23
 crbug.com/1242243 external/wpt/css/css-paint-api/parse-input-arguments-018.https.html [ Crash Failure Pass ]
-crbug.com/1242243 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html [ Crash Failure Pass ]
 
 # Sheriff 2021-08-25
 crbug.com/1243128 [ Win ] external/wpt/web-share/disabled-by-permissions-policy.https.sub.html [ Failure ]
@@ -6203,9 +6269,7 @@
 crbug.com/1233826 [ Mac ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-local-time-null-2.https.html [ Crash Failure Pass ]
 # Also reported as failing via crbug.com/1233766:
 crbug.com/1233826 [ Mac ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-cancel.https.html [ Crash Failure Pass ]
-crbug.com/1250666 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-paint-error.https.html [ Pass Timeout ]
 # Previously reported as failing via crbug.com/626703:
-crbug.com/1236558 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/no-op-animation.https.html [ Crash Failure Pass ]
 crbug.com/1233766 [ Mac ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-local-time-before-start.https.html [ Crash Failure Pass ]
 crbug.com/1233766 [ Mac ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-get-timing-on-worklet-thread.https.html [ Crash Failure Pass ]
 
@@ -6424,9 +6488,6 @@
 crbug.com/1339051 [ Linux ] virtual/document-transition/wpt_internal/document-transition/content-with-transform-new-image.html [ Failure ]
 crbug.com/1339051 [ Linux ] virtual/document-transition/wpt_internal/document-transition/object-view-box-old-image.html [ Failure ]
 crbug.com/1339051 [ Linux ] virtual/document-transition/wpt_internal/document-transition/web-animations-api.html [ Failure ]
-crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-canvasFilter.tentative.https.html [ Failure ]
-crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-filter.https.html [ Failure ]
-crbug.com/1339051 [ Linux ] virtual/off-main-thread-css-paint/http/tests/csspaint/shadow-scale-with-page-zoom.html [ Failure ]
 crbug.com/1339051 [ Linux ] virtual/oopr-canvas2d/fast/canvas/canvas-createImageBitmap-out-of-bounds-src.html [ Failure ]
 crbug.com/1339051 [ Linux ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/nested-render-surfaces.html [ Failure ]
 
@@ -6441,25 +6502,6 @@
 crbug.com/1233826 virtual/threaded/external/wpt/animation-worklet/worklet-animation-local-time-after-duration.https.html [ Skip ]
 crbug.com/930462 external/wpt/animation-worklet/worklet-animation-pause-resume.https.html [ Skip ]
 crbug.com/930462 virtual/threaded/external/wpt/animation-worklet/worklet-animation-pause-resume.https.html [ Skip ]
-crbug.com/1287915 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/non-registered-property-value.https.html [ Skip ]
-crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-010.https.html [ Skip ]
-crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-010.https.html [ Skip ]
-crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-012.https.html [ Skip ]
-crbug.com/1233826 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-017.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-021.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/background-repeat-x.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-005.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/one-custom-property-animation.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-011.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-004.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-background-image-tiled-002.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-015.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-004.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-012.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-003.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-002.https.html [ Skip ]
-crbug.com/1123886 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-004.https.html [ Skip ]
 
 # Sheriff 2021-09-29
 crbug.com/1254163 [ Mac ] virtual/scroll-unification/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ Failure ]
@@ -6642,7 +6684,6 @@
 
 # Sheriff 2021-12-30
 crbug.com/1229096 [ Win ] fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html [ Failure Pass ]
-crbug.com/1279758 [ Win10.20h2 ] virtual/threaded-prefer-compositing/fast/scrolling/scroll-animation-on-by-default.html [ Failure Pass ]
 crbug.com/1280736 [ Win10.20h2 ] http/tests/inspector-protocol/network/blocked-setcookie-same-site-strict-browser-navigate.js [ Pass Timeout ]
 crbug.com/1280736 [ Win10.20h2 ] http/tests/inspector-protocol/network/blocked-setcookie-same-site-strict-js-navigate.js [ Pass Timeout ]
 crbug.com/1280736 [ Win10.20h2 ] http/tests/inspector-protocol/network/blocked-setcookie-same-site-strict-js-subresource.js [ Pass Timeout ]
@@ -6674,44 +6715,6 @@
 crbug.com/1225606 external/wpt/sanitizer-api/sanitizer-names.https.html [ Failure ]
 crbug.com/1225606 virtual/mathml-disabled/sanitizer-api-math-namespace-designator.html [ Failure ]
 
-# Flaky failures in finding the reference file on Mac
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/color-custom-property-animation.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-002.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/geometry-border-image-005.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/hidpi/canvas-transform.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-constructor-error.https.html [ Failure Pass ]
-crbug.com/1250666 crbug.com/1286944 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Failure Pass Timeout ]
-crbug.com/1286944 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/overdraw.https.html [ Failure Pass Timeout ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-arguments-var.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint-function-arguments.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-canvasFilter.tentative.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-conicGradient.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-gradient.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-rects.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/paint2d-rects.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-002.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-009.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-013.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/parse-input-arguments-017.https.html [ Failure Pass ]
-crbug.com/1341471 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-003.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-007.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-invalidation-001.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-stylemap.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-001.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-001.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-001.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-002.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-002.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-009.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-016.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/setTransform-004.https.html [ Failure Pass ]
-crbug.com/1250666 crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-before-load.https.html [ Failure Pass Timeout ]
-crbug.com/1250666 crbug.com/1286944 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/valid-image-after-load.https.html [ Failure Pass Timeout ]
-crbug.com/1286944 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-009.https.html [ Failure ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-011.https.html [ Failure Pass ]
-crbug.com/1286944 [ Mac12 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-interpolation-001.https.html [ Failure Pass ]
-
 # Temporarily disabled to unblock https://crrev.com/c/3657449
 crbug.com/1183990 http/tests/devtools/bindings/bindings-frame-attach-detach.js [ Failure Pass ]
 crbug.com/1183990 http/tests/devtools/bindings/bindings-frame-navigate.js [ Failure Pass ]
@@ -6737,7 +6740,6 @@
 # Temporarily disable test to allow fixing of devtools path escaping
 crbug.com/1094436 http/tests/devtools/overrides/project-added-with-existing-files-bind.js [ Failure Timeout ]
 crbug.com/1256763 virtual/gpu-rasterization/images/color-profile-background-image-cover.html [ Failure Pass ]
-crbug.com/1288136 [ Mac ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-005.https.html [ Failure Pass ]
 
 # Sheriff 2022-01-18
 crbug.com/1288264 [ Win ] http/tests/fetch/serviceworker-proxied/thorough/redirect-loop-base-https-other-https.html [ Pass Timeout ]
@@ -6944,9 +6946,6 @@
 crbug.com/1314314 virtual/percent-based-scrolling/fast/scrolling/scrollbars/mouse-autoscrolling-on-deleted-scrollbar.html [ Skip ]
 crbug.com/1314323 [ Win ] virtual/compositor-threaded-percent-based-scrolling/fast/scrolling/wheel-scrolling-over-custom-scrollbar.html [ Skip ]
 
-# Sheriff 2022-04-14
-crbug.com/1095540 [ Mac ] virtual/threaded-prefer-compositing/fast/scrolling/resize-corner-tracking-touch.html [ Skip ]
-
 crbug.com/1313970 virtual/fenced-frame-shadow-dom/wpt_internal/fenced_frame/visual-viewport.https.html [ Failure ]
 
 # Sheriff 2022-04-08
@@ -7043,9 +7042,6 @@
 crbug.com/1295890 [ Win11 ] http/tests/eventsource/workers/eventsource-cors-no-server.html [ Skip Timeout ]
 crbug.com/1295890 [ Win11 ] http/tests/security/document-domain-canonicalizes-iframe.html [ Skip Timeout ]
 
-# Sheriff 2022-05-04
-crbug.com/1309533 [ Win ] virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness.html [ Failure ]
-
 crbug.com/1322405 external/wpt/fetch/metadata/generated/window-history.https.sub.html [ Pass Timeout ]
 crbug.com/1322405 virtual/plz-dedicated-worker/external/wpt/fetch/metadata/generated/window-history.https.sub.html [ Pass Timeout ]
 
@@ -7166,6 +7162,13 @@
 crbug.com/1341090 external/wpt/webmessaging/with-ports/021.html [ Failure Pass ]
 crbug.com/1341090 external/wpt/webmessaging/without-ports/021.html [ Failure Pass ]
 
+# Temporarily disable to unblock: https://crrev.com/c/3575416
+crbug.com/1342428 http/tests/devtools/application-panel/resources-panel-iframe-idb.js [ Skip ]
+crbug.com/1342428 http/tests/devtools/application-panel/resources-panel-on-navigation.js [ Skip ]
+crbug.com/1342428 http/tests/devtools/application-panel/resources-panel-resource-preview.js [ Skip ]
+crbug.com/1342428 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Skip ]
+crbug.com/1342428 http/tests/devtools/application-panel/resources-panel-websql.js [ Skip ]
+
 # Disable test to land a DevTools change
 crbug.com/1299832 http/tests/devtools/extensions/extensions-api.js [ Skip ]
 
diff --git a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/autocapitalization/autocapitalize.html b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/autocapitalization/autocapitalize.html
index 392ada47..49ee1432 100644
--- a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/autocapitalization/autocapitalize.html
+++ b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/autocapitalization/autocapitalize.html
@@ -8,15 +8,15 @@
 
 test(function() {
     assert_true('autocapitalize' in document.createElement('input'));
-}, "Test that the autocapitalize is avaible on HTMLInputElement.")
+}, "Test that the autocapitalize is available on HTMLInputElement.")
 
 test(function() {
     assert_true('autocapitalize' in document.createElement('textarea'));
-}, "Test that the autocapitalize is avaible on HTMLTextAreaElement.")
+}, "Test that the autocapitalize is available on HTMLTextAreaElement.")
 
 test(function() {
     assert_true('autocapitalize' in document.createElement('div'));
-}, "Test that the autocapitalize is avaible on div.")
+}, "Test that the autocapitalize is available on div.")
 
 test(function() {
   var elements = [ document.createElement('input'),
diff --git a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle-transfer.html b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle-transfer.html
index 9e8f318..2db71c04 100644
--- a/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle-transfer.html
+++ b/third_party/blink/web_tests/external/wpt/media-source/dedicated-worker/mediasource-worker-handle-transfer.html
@@ -20,29 +20,27 @@
       'window must have MediaSourceHandle visibility');
 }
 
-function get_handle_from_new_worker(t) {
+function get_handle_from_new_worker(
+    t, script = 'mediasource-worker-handle-transfer-to-main.js') {
   return new Promise((r) => {
-    let worker = new Worker('mediasource-worker-handle-transfer-to-main.js');
-    worker.addEventListener(
-        'message', 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');
-              r({worker, handle});
-              break;
-            default:
-              assert_unreached('Unexpected message subject: ' + subject);
-          }
-        }),
-        {once: true});
+    let worker = new Worker(script);
+    worker.addEventListener('message', 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');
+          r({worker, handle});
+          break;
+        default:
+          assert_unreached('Unexpected message subject: ' + subject);
+      }
+    }));
   });
 }
 
@@ -224,6 +222,93 @@
   assert_equals(video.srcObject, null);
 }, 'A detached (already transferred away) MediaSourceHandle cannot successfully load when assigned to srcObject');
 
+promise_test(async t => {
+  assert_mseiw_supported();
+  // Get a handle from a worker that is prepared to buffer real media once its
+  // MediaSource instance attaches and 'sourceopen' is dispatched. Unlike
+  // earlier cases in this file, we need positive indication from precisely one
+  // of multiple media elements that the attachment and playback succeeded.
+  let {worker, handle} =
+      await get_handle_from_new_worker(t, 'mediasource-worker-play.js');
+  assert_true(
+      handle instanceof MediaSourceHandle, 'must be a MediaSourceHandle');
+
+  let videos = [];
+  const NUM_ELEMENTS = 5;
+  for (let i = 0; i < NUM_ELEMENTS; ++i) {
+    let v = document.createElement('video');
+    videos.push(v);
+    document.body.appendChild(v);
+  }
+
+  await new Promise((r) => {
+    let errors = 0;
+    let endeds = 0;
+
+    // Setup handlers to expect precisely 1 ended and N-1 errors.
+    videos.forEach((v) => {
+      v.addEventListener(
+          'error', t.step_func(e => {
+            // Confirm expected error and states resulting from the "dedicated
+            // media source failure steps":
+            // https://html.spec.whatwg.org/multipage/media.html#dedicated-media-source-failure-steps
+            let err = v.error;
+            assert_true(err instanceof MediaError);
+            assert_equals(err.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
+            assert_equals(
+                v.readyState, HTMLMediaElement.HAVE_NOTHING,
+                'load failure should occur long before parsing any appended metadata.');
+            assert_equals(v.networkState, HTMLMediaElement.NETWORK_NO_SOURCE);
+
+            errors++;
+            if (errors + endeds == videos.length && endeds == 1)
+              r();
+          }),
+          {once: true});
+      v.addEventListener(
+          'ended', t.step_func(e => {
+            endeds++;
+            if (errors + endeds == videos.length && endeds == 1)
+              r();
+          }),
+          {once: true});
+      v.srcObject = handle;
+      assert_equals(
+          v.networkState, HTMLMediaElement.NETWORK_NO_SOURCE,
+          'before async load start, networkState should be NETWORK_NO_SOURCE');
+    });
+
+    let playPromises = [];
+    videos.forEach((v) => {
+      playPromises.push(v.play());
+    });
+
+    // Ignore playPromise success/rejection, if any.
+    playPromises.forEach((p) => {
+      if (p !== undefined) {
+        p.then(_ => {}).catch(_ => {});
+      }
+    });
+  });
+
+  // Once the handle has been assigned as srcObject, it must fail transfer
+  // steps.
+  assert_throws_dom('DataCloneError', function() {
+    worker.postMessage(handle, [handle]);
+  }, 'transferring handle that is currently srcObject on multiple elements, fails');
+  videos.forEach((v) => {
+    assert_equals(v.srcObject, handle);
+    v.srcObject = null;
+  });
+
+  assert_throws_dom('DataCloneError', function() {
+    worker.postMessage(handle, [handle]);
+  }, 'transferring handle that was srcObject on multiple elements, then was unset on them, should also fail');
+  videos.forEach((v) => {
+    assert_equals(v.srcObject, null);
+  });
+}, 'Precisely one load of the same MediaSourceHandle assigned synchronously to multiple media element srcObjects succeeds');
+
 fetch_tests_from_worker(new Worker('mediasource-worker-handle-transfer.js'));
 
 </script>
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 0292b13..455a2240 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
@@ -9,22 +9,26 @@
 
 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(
+      MediaSource.hasOwnProperty('canConstructInDedicatedWorker'),
+      'MediaSource hasOwnProperty \'canConstructInDedicatedWorker\'');
+  assert_true(
+      MediaSource.canConstructInDedicatedWorker,
+      'MediaSource.canConstructInDedicatedWorker');
 
-  const video = document.createElement("video");
+  const video = document.createElement('video');
   document.body.appendChild(video);
-  video.onerror = t.unreached_func("video element error");
+  video.onerror = t.unreached_func('video element error');
   video.onended = t.step_func_done();
 
-  let worker = new Worker("mediasource-worker-play.js");
-  worker.onerror = t.unreached_func("worker error");
+  let worker = new Worker('mediasource-worker-play.js');
+  worker.onerror = t.unreached_func('worker error');
   worker.onmessage = t.step_func(e => {
     let subject = e.data.subject;
-    assert_true(subject != undefined, "message must have a subject field");
+    assert_true(subject != undefined, 'message must have a subject field');
     switch (subject) {
       case messageSubject.ERROR:
-        assert_unreached("Worker error: " + e.data.info);
+        assert_unreached('Worker error: ' + e.data.info);
         break;
       case messageSubject.HANDLE:
         const handle = e.data.info;
@@ -32,13 +36,13 @@
         video.play();
         break;
       default:
-        assert_unreached("Unexpected message subject: " + subject);
+        assert_unreached('Unexpected message subject: ' + subject);
     }
   });
-}, "Test worker MediaSource construction, attachment, buffering and basic playback");
+}, 'Test worker MediaSource construction, attachment, buffering and basic playback');
 
-// TODO(https://crbug.com/878133): Test multiple attachments to same worker
-// MediaSource racing each other: precisely one should win the race.
+// See mediasource-worker-handle-transfer.html for a case that tests race of
+// multiple simultaneous attachments of same handle to multiple elements.
 
 </script>
 </body>
diff --git a/third_party/blink/web_tests/fast/compositor-wheel-scroll-latching/non-animated-scroll/subpixel-accumulation.html b/third_party/blink/web_tests/fast/compositor-wheel-scroll-latching/non-animated-scroll/subpixel-accumulation.html
index a640a82..5b96ee1b 100644
--- a/third_party/blink/web_tests/fast/compositor-wheel-scroll-latching/non-animated-scroll/subpixel-accumulation.html
+++ b/third_party/blink/web_tests/fast/compositor-wheel-scroll-latching/non-animated-scroll/subpixel-accumulation.html
@@ -47,12 +47,13 @@
     // Scroll horizontally first. Ensure we scrolled the div since otherwise we
     // may pass the test vacuously. See crbug.com/801381 for the case we're
     // guarding against.
-    const expectedScroll = 10;
+    const pixelsToScroll = 10;
     const { x: pixelsToScrollX, y: pixelsToScrollY } = calculatePixelsToScroll(
-      document.scrollingElement, expectedScroll, expectedScroll
+      document.scrollingElement, pixelsToScroll, pixelsToScroll
     );
     await smoothScroll(
-      pixelsToScrollX, 50, 50, WHEEL_SOURCE_TYPE, 'right', 1000
+      pixelsToScrollX, 50, 50, WHEEL_SOURCE_TYPE, 'right', 1000,
+      false /* precise_scrolling_deltas */
     );
 
     // Wait a bit since the scroll gesture resolves when the ScrollEnd is sent
@@ -69,14 +70,18 @@
           "Sanity check, if this fails the test isn't in the correct state.");
     });
 
+    const { y: expectedScrollY } = (
+      calculateExpectedScroll(document.scrollingElement, 0, pixelsToScrollY)
+    );
     // Now scroll vertically. The scroller shouldn't have any vertical scroll
     // extent so the window should scroll.
     await smoothScroll(
-      pixelsToScrollY, 50, 50, WHEEL_SOURCE_TYPE, 'down', 1000
+      pixelsToScrollY, 50, 50, WHEEL_SOURCE_TYPE, 'down', 1000,
+      false /* precise_scrolling_deltas */
     );
     await nFrames(2);
     t.step(() => {
-      assert_approx_equals(window.scrollY, expectedScroll, 0.1);
+      assert_approx_equals(window.scrollY, expectedScrollY, 0.1);
     });
     t.done();
   }
diff --git a/third_party/blink/web_tests/fast/events/wheel/wheelevent-ctrl.html b/third_party/blink/web_tests/fast/events/wheel/wheelevent-ctrl.html
index a0c777d..a7efa56 100644
--- a/third_party/blink/web_tests/fast/events/wheel/wheelevent-ctrl.html
+++ b/third_party/blink/web_tests/fast/events/wheel/wheelevent-ctrl.html
@@ -2,6 +2,7 @@
 <script src="../../../resources/gesture-util.js"></script>
 <script src="../../../resources/testharness.js"></script>
 <script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
 
 <span id="parent">
     <div id="target" style="border:solid 1px green; width:220px; height:70px; overflow:scroll; white-space:nowrap;">
@@ -18,10 +19,16 @@
 <script>
 var scrollAmount = 1;
 var last_event = null;
-// TODO(crbug.com/1204176): expectedDeltaY will not match expectations if
-// percent-based scrolling is enabled.
-var expectedDeltaY = scrollAmount * pixelsPerTick();
 var testDiv = document.getElementById('target');
+var expectedScrollY =
+      calculateExpectedScroll(testDiv, 0, scrollAmount * pixelsPerTick()).y;
+var expectedScrollParentY =
+      calculateExpectedScroll(document.scrollingElement,
+      0, scrollAmount * pixelsPerTick()).y;
+var expectedDeltaY =
+      scrollAmount * (isPercentBasedScrollingEnabled() ? 100 : pixelsPerTick());
+var expectedPreciseDeltaY = pixelsPerTick();
+
 var scroller_target = elementCenter(testDiv);
 
 // Reset the page state and last wheel event.
@@ -59,8 +66,8 @@
   await wheelTick(0, scrollAmount, scroller_target, SPEED_INSTANT);
   await wheelPromise;
   await waitForAnimationEndTimeBased(() => { return testDiv.scrollTop; });
-  assert_equals(testDiv.scrollTop, expectedDeltaY);
-  assert_equals(last_event.deltaY, expectedDeltaY);
+  assert_equals(testDiv.scrollTop, expectedScrollY);
+  assert_approx_equals(last_event.deltaY, expectedDeltaY, 0.00001);
   assert_false(last_event.ctrlKey);
 }, "Div: No-Ctrl wheel scrolls.");
 
@@ -99,8 +106,8 @@
                            Modifiers.CONTROL);
   await wheelPromise;
   await waitForAnimationEndTimeBased(() => { return window.scrollY; });
-  assert_equals(window.scrollY, expectedDeltaY);
-  assert_equals(last_event.deltaY, expectedDeltaY);
+  assert_equals(window.scrollY, expectedPreciseDeltaY);
+  assert_equals(last_event.deltaY, expectedPreciseDeltaY);
   assert_true(last_event.ctrlKey);
 }, "Doc: Ctrl+high precision touchpad scroll scrolls.");
 
@@ -111,8 +118,8 @@
   await wheelTick(0, scrollAmount, document_target, SPEED_INSTANT);
   await wheelPromise;
   await waitForAnimationEndTimeBased(() => { return window.scrollY; });
-  assert_equals(window.scrollY, expectedDeltaY);
-  assert_equals(last_event.deltaY, expectedDeltaY);
+  assert_equals(window.scrollY, expectedScrollParentY);
+  assert_approx_equals(last_event.deltaY, expectedDeltaY, 0.00001);
   assert_false(last_event.ctrlKey);
 }, "Doc: No-Ctrl wheel scrolls.");
 
diff --git a/third_party/blink/web_tests/fast/hidpi/static/mousewheel-scroll-amount.html b/third_party/blink/web_tests/fast/hidpi/static/mousewheel-scroll-amount.html
index 71ae43af..328c8b8 100644
--- a/third_party/blink/web_tests/fast/hidpi/static/mousewheel-scroll-amount.html
+++ b/third_party/blink/web_tests/fast/hidpi/static/mousewheel-scroll-amount.html
@@ -2,6 +2,7 @@
 <script src="../../../resources/gesture-util.js"></script>
 <script src="../../../resources/testharness.js"></script>
 <script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
 
 <style type="text/css">
     body {
@@ -24,8 +25,10 @@
     await waitForAnimationEndTimeBased( () => {
         return document.scrollingElement.scrollTop;
     });
-    assert_equals(document.scrollingElement.scrollLeft, 0);
-    assert_equals(document.scrollingElement.scrollTop, pixelsPerTick());
+    const {x: expectedScrollX, y: expectedScrollY} = 
+        calculateExpectedScroll(document.scrollingElement, 0, pixelsPerTick());
+    assert_approx_equals(document.scrollingElement.scrollLeft, expectedScrollX, 0.0001);
+    assert_approx_equals(document.scrollingElement.scrollTop, expectedScrollY, 0.0001);
 }, "One vertical wheel tick scrolls the right number of pixels in high dpi mode.");
 
 promise_test(async () => {
@@ -34,8 +37,10 @@
     await waitForAnimationEndTimeBased( () => {
         return document.scrollingElement.scrollLeft;
     });
-    assert_equals(document.scrollingElement.scrollLeft, pixelsPerTick());
-    assert_equals(document.scrollingElement.scrollTop, 0);
+    const {x: expectedScrollX, y: expectedScrollY} = 
+        calculateExpectedScroll(document.scrollingElement, pixelsPerTick(), 0);
+    assert_approx_equals(document.scrollingElement.scrollLeft, expectedScrollX, 0.0001);
+    assert_approx_equals(document.scrollingElement.scrollTop, expectedScrollY, 0.0001);
 }, "One horizontal wheel tick scrolls the right number of pixels in high dpi mode.");
 
 promise_test(async () => {
@@ -44,8 +49,10 @@
     await waitForAnimationEndTimeBased( () => {
         return document.scrollingElement.scrollTop;
     });
-    assert_equals(document.scrollingElement.scrollLeft, 0);
-    assert_equals(document.scrollingElement.scrollTop, 2 * pixelsPerTick());
+    const {x: expectedScrollX, y: expectedScrollY} = 
+        calculateExpectedScroll(document.scrollingElement, 0, pixelsPerTick() * 2);
+    assert_approx_equals(document.scrollingElement.scrollLeft, expectedScrollX, 0.0001);
+    assert_approx_equals(document.scrollingElement.scrollTop, expectedScrollY, 0.0001);
 }, "Two vertical wheel ticks scroll the right number of pixels in high dpi mode.");
 
 promise_test(async () => {
@@ -54,7 +61,9 @@
     await waitForAnimationEndTimeBased( () => {
         return document.scrollingElement.scrollLeft;
     });
-    assert_equals(document.scrollingElement.scrollLeft, 2 * pixelsPerTick());
-    assert_equals(document.scrollingElement.scrollTop, 0);
+    const {x: expectedScrollX, y: expectedScrollY} = 
+        calculateExpectedScroll(document.scrollingElement, pixelsPerTick() * 2, 0);
+    assert_approx_equals(document.scrollingElement.scrollLeft, expectedScrollX, 0.0001);
+    assert_approx_equals(document.scrollingElement.scrollTop, expectedScrollY, 0.0001);
 }, "Two horizontal wheel ticks scroll the right number of pixels in high dpi mode.");
 </script>
diff --git a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html
index b637749..f3b0dbc 100644
--- a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html
+++ b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html
@@ -42,10 +42,10 @@
 
     // Scroll 3 ticks diagonally.
     await smoothScroll(3 * pixelsPerTick() , x, y, source, 'downright',
-      SPEED_INSTANT);
+      SPEED_INSTANT, false /* precise_scrolling_deltas */);
     // Undo 2 ticks in each direction.
     await smoothScroll(2 * pixelsPerTick(), x, y, source, 'upleft',
-      SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+      SPEED_INSTANT, false /* precise_scrolling_deltas */);
 
     await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; });
     await waitForAnimationEndTimeBased(() => { return scroller.scrollLeft; });
@@ -57,7 +57,7 @@
     // Undo the last tick in each direction to reset the scroll state before
     // starting the second test.
     await smoothScroll(1 * pixelsPerTick(), x, y, source, 'upleft',
-      SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+      SPEED_INSTANT, false /* precise_scrolling_deltas */);
 
     await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; });
     await waitForAnimationEndTimeBased(() => { return scroller.scrollLeft; });
@@ -74,19 +74,19 @@
 
     // Scroll down 3 ticks.
     await smoothScroll(1 * pixelsPerTick(), x, y, source, 'down',
-        SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
     await smoothScroll(2 * pixelsPerTick(), x, y, source, 'down',
-        SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
     // Scroll right 3 ticks.
     await smoothScroll(1 * pixelsPerTick(), x, y, source, 'right',
-        SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
     await smoothScroll(2 * pixelsPerTick(), x, y, source, 'right',
-        SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
     // Undo 1 tick in each direction.
     await smoothScroll(1 * pixelsPerTick(), x, y, source, 'up',
-        SPEED_INSTANT, !isPercentBasedScrollingEnabled());
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
     await smoothScroll(1 * pixelsPerTick(), x, y, source, 'left',
-        SPEED_INSTANT);
+        SPEED_INSTANT, false /* precise_scrolling_deltas */);
 
     await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; });
     await waitForAnimationEndTimeBased(() => { return scroller.scrollLeft; });
diff --git a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html
index be57f8c..408fc36 100644
--- a/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html
+++ b/third_party/blink/web_tests/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <script src="../../../resources/testharness.js"></script>
 <script src="../../../resources/testharnessreport.js"></script>
 <script src="../../../resources/gesture-util.js"></script>
@@ -47,7 +48,7 @@
     }
 
     if (ch.style.height != "100")
-      ch.style.height = changerY;
+      ch.style.height = changerY + "px";
   }
 
   window.onload = async () => {
@@ -55,7 +56,8 @@
     document.addEventListener("scroll", scrollListener);
 
     // Smooth scroll.
-    smoothScroll(userScrollY, 100, 100, source, 'down', SPEED_INSTANT);
+    smoothScroll(userScrollY, 100, 100, source, 'down', 
+                 SPEED_INSTANT, false /* precise_scrolling_deltas */);
     await raf();
     document.getElementById('anchor').scrollIntoView();
   }
diff --git a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html
index 6094796..ac77005 100644
--- a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html
+++ b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-element-with-overscroll-behavior.html
@@ -87,11 +87,18 @@
   overscrolled_y_delta = 0;
   await waitForCompositorCommit();
 
+  // When PBS is enabled, the number of 'pixels to scroll' is significantly
+  // distorted (~10k with current params), causing this test to take longer and
+  // time out. Adjusting speed by the distortion means the scroll anomations
+  // take the same time whether PBS is on or off
+  const scroll_speed_factor_x = pixelsToScrollX / pixelsToScroll;
+  const scroll_speed_factor_y = pixelsToScrollY / pixelsToScroll;
+
   // Scroll up on target div and wait for the element with overscroll-y to get
   // overscroll event.
   await smoothScroll(
-    pixelsToScrollY, x, y, source_device, "up", pixelsPerSec,
-    precise_scrolling_delta
+    pixelsToScrollY, x, y, source_device, "up", 
+    pixelsPerSec * scroll_speed_factor_x, precise_scrolling_delta
   );
   await waitFor(() => { return overscrolled_y_delta < 0; },
       'Expected element did not receive overscroll event after scroll up on ' +
@@ -101,8 +108,8 @@
   // Scroll left on target div and wait for the element with overscroll-x to
   // get overscroll event.
   await smoothScroll(
-    pixelsToScrollX, x, y, source_device, "left", pixelsPerSec,
-    precise_scrolling_delta
+    pixelsToScrollX, x, y, source_device, "left", 
+    pixelsPerSec * scroll_speed_factor_y, precise_scrolling_delta
   );
   await waitFor(() => { return overscrolled_x_delta < 0; },
       'Expected element did not receive overscroll event after scroll left ' +
diff --git a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html
index 9e163e3..47aa747 100644
--- a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html
+++ b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-scrolled-element.html
@@ -62,9 +62,16 @@
   overscrolled_y_delta = 0;
   await waitForCompositorCommit();
 
+  // When PBS is enabled, the number of 'pixels to scroll' is significantly distorted
+  // (~10k with current params), causing this test to take longer and time out
+  // Adjusting speed by the distortion means the scroll anomations take the same
+  // time whether PBS is on or off
+  const scroll_speed_factor_x = pixelsToScrollX / pixelsToScroll;
+  const scroll_speed_factor_y = pixelsToScrollY / pixelsToScroll;
+
   // Do a horizontal scroll and wait for overscroll event.
   await smoothScroll(
-    pixelsToScrollX, x, y, source_device, "right", pixelsPerSec,
+    pixelsToScrollX, x, y, source_device, "right", pixelsPerSec * scroll_speed_factor_x,
     precise_scrolling_delta
   );
   await waitFor(() => { return overscrolled_x_delta > 0; },
@@ -78,7 +85,7 @@
 
   // Do a vertical scroll and wait for overscroll event.
   await smoothScroll(
-    pixelsToScrollY, x, y, source_device, "down", pixelsPerSec,
+    pixelsToScrollY, x, y, source_device, "down", pixelsPerSec * scroll_speed_factor_y,
     precise_scrolling_delta
   );
   await waitFor(() => { return overscrolled_y_delta > 0; },
diff --git a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-window.html b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-window.html
index a152734..fdba51d 100644
--- a/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-window.html
+++ b/third_party/blink/web_tests/fast/scrolling/events/overscroll-event-fired-to-window.html
@@ -44,6 +44,7 @@
 const { y: pixelsToScrollY } = calculatePixelsToScroll(
   target_div, pixelsToScroll, pixelsToScroll
 );
+const scroll_speed_factor_y = pixelsToScrollY / pixelsToScroll;
 
 var window_received_overscroll = false;
 
@@ -62,7 +63,7 @@
 
   // Scroll up on target div and wait for the window to get overscroll event.
   await smoothScroll(
-    pixelsToScrollY, x, y, source_device, "up", pixelsPerSec,
+    pixelsToScrollY, x, y, source_device, "up", pixelsPerSec * scroll_speed_factor_y,
     precise_scrolling_delta
   );
   await waitFor(() => { return window_received_overscroll; },
diff --git a/third_party/blink/web_tests/fast/scrolling/overflow-scrollability.html b/third_party/blink/web_tests/fast/scrolling/overflow-scrollability.html
index 43848f16..c15a887f 100644
--- a/third_party/blink/web_tests/fast/scrolling/overflow-scrollability.html
+++ b/third_party/blink/web_tests/fast/scrolling/overflow-scrollability.html
@@ -77,7 +77,8 @@
     const expectedScroll = calculateExpectedScroll(div, pixelsToScroll, pixelsToScroll);
     await mouseMoveTo(x, y);
 
-    await smoothScroll(pixelsToScroll, x, y, mouse, 'down', SPEED_INSTANT);
+    await smoothScroll(pixelsToScroll, x, y, mouse, 'down',
+                       SPEED_INSTANT, false /* precise_scrolling_deltas */);
     let assertDescription = `${div_id} vertical scroll failed`;
     if (can_scroll)
       assert_approx_equals(div.scrollTop, expectedScroll.y, 0.01, assertDescription);
@@ -85,7 +86,8 @@
       assert_equals(div.scrollTop, 0, assertDescription);
     }
 
-    await smoothScroll(pixelsToScroll, x, y, mouse, 'right', SPEED_INSTANT);
+    await smoothScroll(pixelsToScroll, x, y, mouse, 'right',
+                       SPEED_INSTANT, false /* precise_scrolling_deltas */);
     assertDescription = `${div_id} horizontal scroll failed`;
     if (can_scroll) {
       assert_approx_equals(div.scrollLeft, expectedScroll.x, 0.01, assertDescription);
diff --git a/third_party/blink/web_tests/fast/scrolling/scroll-animation-on-by-default.html b/third_party/blink/web_tests/fast/scrolling/scroll-animation-on-by-default.html
index 75da4662..1d190d8 100644
--- a/third_party/blink/web_tests/fast/scrolling/scroll-animation-on-by-default.html
+++ b/third_party/blink/web_tests/fast/scrolling/scroll-animation-on-by-default.html
@@ -4,6 +4,7 @@
 <script src="../../resources/testharnessreport.js"></script>
 <script src="../../resources/gesture-util.js"></script>
 <script src="../../resources/scrollbar-util.js"></script>
+<script src="../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
 <body style="height: 1000px; width: 1000px">
 <script>
 window.onload = () => {
@@ -54,18 +55,23 @@
     resetScrollOffset(document.scrollingElement);
     await waitForCompositorCommit();
 
+    const scrollAmountY = 72;
+    const expectedScrollY = isPercentBasedScrollingEnabled() ?
+          calculateExpectedScroll(document.scrollingElement, 0, scrollAmountY).y
+        : scrollAmountY;
+
     // Start at 0, perform a mousewheel tick and check that scrollY animates at
     // least once. This test is relevant only when running in threaded mode
     // (--enable-threaded-compositing).
     assert_equals(window.scrollY, 0, "Scroller is expected to be at 0 offset.");
-    initBounds(0, 72);
-    await smoothScrollWithXY(0, 72, window.innerWidth / 2, window.innerHeight / 2,
+    initBounds(0, expectedScrollY);
+    await smoothScrollWithXY(0, scrollAmountY, window.innerWidth / 2, window.innerHeight / 2,
                              GestureSourceType.MOUSE_INPUT,
                              SPEED_INSTANT, false /* precise_scrolling_deltas */,
                              false /* scroll_by_page */, true /* cursor_visible */,
                              false /* scroll_by_percentage */);
     await waitForAnimationEndTimeBased(() => {return window.scrollY;});
-    assert_equals(window.scrollY, 72, "Unexpected scroll offset for mousewheel tick.");
+    assert_approx_equals(window.scrollY, expectedScrollY, 0.0001, "Unexpected scroll offset for mousewheel tick.");
     assert_true(animated_scroll, "Mousewheel tick did not animate.");
   }, "Test mouse wheel tick is animated.");
 }
diff --git a/third_party/blink/web_tests/fast/scrolling/wheel-and-touch-scroll-use-count.html b/third_party/blink/web_tests/fast/scrolling/wheel-and-touch-scroll-use-count.html
index d9a8e0354..f7d5b8f 100644
--- a/third_party/blink/web_tests/fast/scrolling/wheel-and-touch-scroll-use-count.html
+++ b/third_party/blink/web_tests/fast/scrolling/wheel-and-touch-scroll-use-count.html
@@ -2,6 +2,7 @@
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <script src='../../resources/gesture-util.js'></script>
+<script src="../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
 <style>
 
   ::-webkit-scrollbar {
@@ -39,7 +40,11 @@
 async function scrollDown(pixels_to_scroll, gesture_source_type, precise_deltas) {
   await waitForCompositorCommit();
   const previous_scroll_offset = scrollable.scrollTop;
-
+  const expectedScrollY = (isPercentBasedScrollingEnabled() && 
+               gesture_source_type == GestureSourceType.MOUSE_INPUT && 
+              !precise_deltas) ? 
+                  calculateExpectedScroll(scrollable, 0, pixels_to_scroll).y : 
+                  pixels_to_scroll;
   await smoothScroll(pixels_to_scroll, start_x, start_y, gesture_source_type,
                     'down', SPEED_INSTANT, precise_deltas);
   await waitFor(() => {
@@ -48,9 +53,9 @@
     // TODO(bokan): Change to precise expectation once https://crbug.com/897520
     // fixed.
     return approx_equals(scrollable.scrollTop - previous_scroll_offset,
-                         pixels_to_scroll,
+                         expectedScrollY,
                          3 /* pixels */);
-  }, "Didn't scroll by approximately expected amount: " + pixels_to_scroll);
+  }, "Didn't scroll by approximately expected amount: " + expectedScrollY);
   await waitForCompositorCommit();
 }
 
diff --git a/third_party/blink/web_tests/synthetic_gestures/animated-wheel-tiny-delta.html b/third_party/blink/web_tests/synthetic_gestures/animated-wheel-tiny-delta.html
index 327683d..576e49a2 100644
--- a/third_party/blink/web_tests/synthetic_gestures/animated-wheel-tiny-delta.html
+++ b/third_party/blink/web_tests/synthetic_gestures/animated-wheel-tiny-delta.html
@@ -2,6 +2,7 @@
 <script src='../resources/testharness.js'></script>
 <script src='../resources/testharnessreport.js'></script>
 <script src='../resources/gesture-util.js'></script>
+<script src="../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
 
 <style>
   body, html {
@@ -14,7 +15,7 @@
   // This test ensures that animated mouse wheel scrolls with tiny amounts are
   // accurately propagated in the renderer.
 
-  async function tryScroll(distance, source) {
+  async function tryScroll(distance, source, expectedScrollY) {
       const x = 400;
       const y = 300;
       const precise_deltas = false;
@@ -30,8 +31,10 @@
                          SPEED_INSTANT,
                          precise_deltas);
 
-      await waitFor(() => { return window.scrollY - scrollYBefore >= distance; },
-                    "Didn't scroll by expected amount: " + distance);
+      
+
+      await waitFor(() => { return window.scrollY - scrollYBefore >= expectedScrollY; },
+                    "Didn't scroll by expected amount: " + expectedScrollY);
       await waitForCompositorCommit();
   }
 
@@ -39,16 +42,20 @@
     const source_type = GestureSourceType.MOUSE_INPUT;
 
     promise_test(async () => {
+      const expectedScrollY = 
+              calculateExpectedScroll(document.scrollingElement, 0, 1).y;
       assert_equals(window.scrollY, 0);
-      await tryScroll(1, source_type);
-      assert_equals(window.scrollY, 1);
+      await tryScroll(1, source_type, expectedScrollY);
+      assert_approx_equals(window.scrollY, expectedScrollY, 0.00001);
     }, 'Synthetic animated ' + GestureSourceType.ToString(source_type) +
        ' gestures accurately scroll delta (0, 1).');
 
     promise_test(async () => {
-      assert_equals(window.scrollY, 1);
-      await tryScroll(2, source_type);
-      assert_equals(window.scrollY, 3);
+      const scrollYBefore = window.scrollY;
+      const expectedScrollY = 
+              calculateExpectedScroll(document.scrollingElement, 0, 2).y;
+      await tryScroll(2, source_type, expectedScrollY);
+      assert_approx_equals(window.scrollY, scrollYBefore + expectedScrollY, 0.00001);
       window.scrollTo(0, 0);
     }, 'Synthetic animated ' + GestureSourceType.ToString(source_type) +
        ' gestures accurately scroll delta (0, 2).');
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 564d049..9c5a77d 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-12-1-47-g8a9192f68
-Revision: 8a9192f68ef0100649502bd8fe17df7f51211521
+Version: VER-2-12-1-48-g7c151abb6
+Revision: 7c151abb6903ddb9c9ed5a1c7b962819c1b2d36f
 CPEPrefix: cpe:/a:freetype:freetype:2.11.1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn
index 75aef4ad..85a4b98 100644
--- a/third_party/ipcz/src/BUILD.gn
+++ b/third_party/ipcz/src/BUILD.gn
@@ -218,6 +218,7 @@
     "ipcz/driver_transport.h",
     "ipcz/fragment.h",
     "ipcz/fragment_descriptor.h",
+    "ipcz/fragment_ref.h",
     "ipcz/link_side.h",
     "ipcz/link_type.h",
     "ipcz/message.h",
@@ -229,6 +230,7 @@
     "ipcz/parcel.h",
     "ipcz/parcel_queue.h",
     "ipcz/portal.h",
+    "ipcz/ref_counted_fragment.h",
     "ipcz/remote_router_link.h",
     "ipcz/router.h",
     "ipcz/sequence_number.h",
@@ -250,6 +252,7 @@
     "ipcz/driver_transport.cc",
     "ipcz/fragment.cc",
     "ipcz/fragment_descriptor.cc",
+    "ipcz/fragment_ref.cc",
     "ipcz/handle_type.h",
     "ipcz/link_side.cc",
     "ipcz/link_type.cc",
@@ -275,6 +278,7 @@
     "ipcz/parcel.cc",
     "ipcz/parcel_queue.cc",
     "ipcz/portal.cc",
+    "ipcz/ref_counted_fragment.cc",
     "ipcz/remote_router_link.cc",
     "ipcz/router.cc",
     "ipcz/router_descriptor.cc",
@@ -330,6 +334,7 @@
     "ipcz/node_connector_test.cc",
     "ipcz/node_link_test.cc",
     "ipcz/parcel_queue_test.cc",
+    "ipcz/ref_counted_fragment_test.cc",
     "ipcz/sequenced_queue_test.cc",
     "reference_drivers/sync_reference_driver_test.cc",
     "remote_portal_test.cc",
diff --git a/third_party/ipcz/src/ipcz/fragment_ref.cc b/third_party/ipcz/src/ipcz/fragment_ref.cc
new file mode 100644
index 0000000..e586924
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/fragment_ref.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 "ipcz/fragment_ref.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "ipcz/fragment.h"
+#include "ipcz/node_link_memory.h"
+#include "ipcz/ref_counted_fragment.h"
+#include "util/ref_counted.h"
+
+namespace ipcz::internal {
+
+GenericFragmentRef::GenericFragmentRef() = default;
+
+GenericFragmentRef::GenericFragmentRef(Ref<NodeLinkMemory> memory,
+                                       const Fragment& fragment)
+    : memory_(std::move(memory)), fragment_(fragment) {}
+
+GenericFragmentRef::~GenericFragmentRef() {
+  reset();
+}
+
+void GenericFragmentRef::reset() {
+  Ref<NodeLinkMemory> memory = std::move(memory_);
+  if (fragment_.is_null()) {
+    return;
+  }
+
+  Fragment fragment;
+  std::swap(fragment, fragment_);
+  if (!fragment.is_addressable()) {
+    return;
+  }
+
+  auto* ref_counted = static_cast<RefCountedFragment*>(fragment.address());
+  if (ref_counted->ReleaseRef() > 1 || !memory) {
+    return;
+  }
+
+  memory->buffer_pool().FreeFragment(fragment);
+}
+
+Fragment GenericFragmentRef::release() {
+  Fragment fragment;
+  std::swap(fragment_, fragment);
+  memory_.reset();
+  return fragment;
+}
+
+}  // namespace ipcz::internal
diff --git a/third_party/ipcz/src/ipcz/fragment_ref.h b/third_party/ipcz/src/ipcz/fragment_ref.h
new file mode 100644
index 0000000..e54135b
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/fragment_ref.h
@@ -0,0 +1,144 @@
+// 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 IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
+#define IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "ipcz/fragment.h"
+#include "ipcz/fragment_descriptor.h"
+#include "ipcz/ref_counted_fragment.h"
+#include "third_party/abseil-cpp/absl/base/macros.h"
+#include "util/ref_counted.h"
+
+namespace ipcz {
+
+class NodeLinkMemory;
+
+namespace internal {
+
+// Base class for any FragmentRef<T>, implementing common behavior for managing
+// the underlying RefCountedFragment.
+class GenericFragmentRef {
+ public:
+  GenericFragmentRef();
+
+  // Does not increase the ref count of the underlying RefCountedFragment,
+  // effectively assuming ownership of a previously acquired ref.
+  GenericFragmentRef(Ref<NodeLinkMemory> memory, const Fragment& fragment);
+
+  ~GenericFragmentRef();
+
+  const Ref<NodeLinkMemory>& memory() const { return memory_; }
+  const Fragment& fragment() const { return fragment_; }
+
+  bool is_null() const { return fragment_.is_null(); }
+  bool is_addressable() const { return fragment_.is_addressable(); }
+  bool is_pending() const { return fragment_.is_pending(); }
+
+  void reset();
+  Fragment release();
+
+  int32_t ref_count_for_testing() const {
+    return AsRefCountedFragment()->ref_count_for_testing();
+  }
+
+ protected:
+  RefCountedFragment* AsRefCountedFragment() const {
+    return static_cast<RefCountedFragment*>(fragment_.address());
+  }
+
+  // The NodeLinkMemory who ultimately owns this fragment's memory. May be null
+  // if the FragmentRef is unmanaged.
+  Ref<NodeLinkMemory> memory_;
+
+  Fragment fragment_;
+};
+
+}  // namespace internal
+
+// Holds a reference to a RefCountedFragment. When this object is destroyed, the
+// underlying ref count is decreased. If the ref count is decreased to zero, the
+// underlying Fragment is returned to its NodeLinkMemory.
+//
+// Some FragmentRefs may be designated as "unmanaged", meaning that they will
+// never attempt to free the underlying Fragment. These refs are used to
+// preserve type compatibility with other similar (but managed) FragmentRefs
+// when the underlying Fragment isn't dynamically allocated and can't be freed.
+//
+// For example most RouterLinkState fragments are dynamically allocated and
+// managed by FragmentRefs, but some instances are allocated at fixed locations
+// within the NodeLinkMemory and cannot be freed or reused. In both cases, ipcz
+// can refer to these objects using a FragmentRef<RouterLinkState>.
+template <typename T>
+class FragmentRef : public internal::GenericFragmentRef {
+ public:
+  static_assert(std::is_base_of<RefCountedFragment, T>::value,
+                "T must inherit RefCountedFragment for FragmentRef<T>");
+
+  constexpr FragmentRef() = default;
+  constexpr FragmentRef(std::nullptr_t) : FragmentRef() {}
+
+  // Adopts an existing ref to the RefCountedFragment located at the beginning
+  // of `fragment`, which is a Fragment owned by `memory.
+  FragmentRef(decltype(RefCountedFragment::kAdoptExistingRef),
+              Ref<NodeLinkMemory> memory,
+              const Fragment& fragment)
+      : GenericFragmentRef(std::move(memory), fragment) {
+    ABSL_ASSERT(memory_);
+    ABSL_ASSERT(fragment_.is_null() || fragment_.size() >= sizeof(T));
+  }
+
+  // Constructs an unmanaged FragmentRef, which references `fragment` and
+  // updates its refcount, but which never attempts to release `fragment` back
+  // to its NodeLinkMemory. This is only safe to use with Fragments which cannot
+  // be freed.
+  FragmentRef(decltype(RefCountedFragment::kUnmanagedRef),
+              const Fragment& fragment)
+      : GenericFragmentRef(nullptr, fragment) {
+    ABSL_ASSERT(fragment_.is_null() || fragment_.size() >= sizeof(T));
+  }
+
+  FragmentRef(const FragmentRef<T>& other)
+      : GenericFragmentRef(other.memory(), other.fragment()) {
+    if (!fragment_.is_null()) {
+      ABSL_ASSERT(fragment_.is_addressable());
+      AsRefCountedFragment()->AddRef();
+    }
+  }
+
+  FragmentRef(FragmentRef<T>&& other) noexcept
+      : GenericFragmentRef(std::move(other.memory_), other.fragment_) {
+    other.release();
+  }
+
+  FragmentRef<T>& operator=(const FragmentRef<T>& other) {
+    reset();
+    memory_ = other.memory();
+    fragment_ = other.fragment();
+    if (!fragment_.is_null()) {
+      ABSL_ASSERT(fragment_.is_addressable());
+      AsRefCountedFragment()->AddRef();
+    }
+    return *this;
+  }
+
+  FragmentRef<T>& operator=(FragmentRef<T>&& other) {
+    reset();
+    memory_ = std::move(other.memory_);
+    fragment_ = other.release();
+    return *this;
+  }
+
+  T* get() const { return static_cast<T*>(fragment_.address()); }
+  T* operator->() const { return get(); }
+  T& operator*() const { return *get(); }
+};
+
+}  // namespace ipcz
+
+#endif  // IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
diff --git a/third_party/ipcz/src/ipcz/node_link_memory.cc b/third_party/ipcz/src/ipcz/node_link_memory.cc
index 5a8aba0..012f26c 100644
--- a/third_party/ipcz/src/ipcz/node_link_memory.cc
+++ b/third_party/ipcz/src/ipcz/node_link_memory.cc
@@ -25,12 +25,11 @@
 // Fixed allocation size for each NodeLink's primary shared buffer.
 constexpr size_t kPrimaryBufferSize = 65536;
 
-}  // namespace
+// The front of the primary buffer is reserved for special current and future
+// uses which require synchronous availability throughout a link's lifetime.
+constexpr size_t kPrimaryBufferReservedHeaderSize = 256;
 
-// This structure always sits at offset 0 in the primary buffer and has a fixed
-// layout according to the NodeLink's agreed upon protocol version. This is the
-// layout for version 0 (currently the only version.)
-struct IPCZ_ALIGN(8) NodeLinkMemory::PrimaryBuffer {
+struct IPCZ_ALIGN(8) PrimaryBufferHeader {
   // Atomic generator for new unique BufferIds to use across the associated
   // NodeLink. This allows each side of a NodeLink to generate new BufferIds
   // spontaneously without synchronization or risk of collisions.
@@ -42,6 +41,51 @@
   std::atomic<uint64_t> next_sublink_id;
 };
 
+static_assert(sizeof(PrimaryBufferHeader) < kPrimaryBufferReservedHeaderSize);
+
+constexpr size_t kPrimaryBufferHeaderPaddingSize =
+    kPrimaryBufferReservedHeaderSize - sizeof(PrimaryBufferHeader);
+
+}  // namespace
+
+// This structure always sits at offset 0 in the primary buffer and has a fixed
+// layout according to the NodeLink's agreed upon protocol version. This is the
+// layout for version 0 (currently the only version.)
+struct IPCZ_ALIGN(8) NodeLinkMemory::PrimaryBuffer {
+  // Header + padding occupies the first 256 bytes.
+  PrimaryBufferHeader header;
+  uint8_t reserved_header_padding[kPrimaryBufferHeaderPaddingSize];
+
+  // Reserved memory for a series of fixed block allocators. Additional
+  // allocators may be adopted by a NodeLinkMemory over its lifetime, but these
+  // ones remain fixed within the primary buffer.
+  std::array<uint8_t, 4096> mem_for_64_byte_blocks;
+  std::array<uint8_t, 12288> mem_for_256_byte_blocks;
+  std::array<uint8_t, 15360> mem_for_512_byte_blocks;
+  std::array<uint8_t, 11264> mem_for_1024_byte_blocks;
+  std::array<uint8_t, 16384> mem_for_2048_byte_blocks;
+
+  BlockAllocator block_allocator_64() {
+    return BlockAllocator(absl::MakeSpan(mem_for_64_byte_blocks), 64);
+  }
+
+  BlockAllocator block_allocator_256() {
+    return BlockAllocator(absl::MakeSpan(mem_for_256_byte_blocks), 256);
+  }
+
+  BlockAllocator block_allocator_512() {
+    return BlockAllocator(absl::MakeSpan(mem_for_512_byte_blocks), 512);
+  }
+
+  BlockAllocator block_allocator_1024() {
+    return BlockAllocator(absl::MakeSpan(mem_for_1024_byte_blocks), 1024);
+  }
+
+  BlockAllocator block_allocator_2048() {
+    return BlockAllocator(absl::MakeSpan(mem_for_2048_byte_blocks), 2048);
+  }
+};
+
 NodeLinkMemory::NodeLinkMemory(Ref<Node> node,
                                DriverMemoryMapping primary_buffer_memory)
     : node_(std::move(node)),
@@ -52,8 +96,17 @@
   static_assert(sizeof(PrimaryBuffer) <= kPrimaryBufferSize,
                 "PrimaryBuffer structure is too large.");
 
-  buffer_pool_.AddBuffer(BufferId{kPrimaryBufferId},
-                         std::move(primary_buffer_memory));
+  buffer_pool_.AddBuffer(kPrimaryBufferId, std::move(primary_buffer_memory));
+  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
+                                      primary_buffer_.block_allocator_64());
+  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
+                                      primary_buffer_.block_allocator_256());
+  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
+                                      primary_buffer_.block_allocator_512());
+  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
+                                      primary_buffer_.block_allocator_1024());
+  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
+                                      primary_buffer_.block_allocator_2048());
 }
 
 NodeLinkMemory::~NodeLinkMemory() = default;
@@ -71,15 +124,21 @@
   PrimaryBuffer& primary_buffer = memory->primary_buffer_;
 
   // The first allocable BufferId is 1, because the primary buffer uses 0.
-  primary_buffer.next_buffer_id.store(1, std::memory_order_relaxed);
+  primary_buffer.header.next_buffer_id.store(1, std::memory_order_relaxed);
 
   // The first allocable SublinkId is kMaxInitialPortals. This way it doesn't
   // matter whether the two ends of a NodeLink initiate their connection with a
   // different initial portal count: neither can request more than
   // kMaxInitialPortals, so neither will be assuming initial ownership of any
   // SublinkIds at or above this value.
-  primary_buffer.next_sublink_id.store(kMaxInitialPortals,
-                                       std::memory_order_release);
+  primary_buffer.header.next_sublink_id.store(kMaxInitialPortals,
+                                              std::memory_order_release);
+
+  primary_buffer.block_allocator_64().InitializeRegion();
+  primary_buffer.block_allocator_256().InitializeRegion();
+  primary_buffer.block_allocator_512().InitializeRegion();
+  primary_buffer.block_allocator_1024().InitializeRegion();
+  primary_buffer.block_allocator_2048().InitializeRegion();
 
   return {
       .node_link_memory = std::move(memory),
@@ -95,12 +154,12 @@
 }
 
 BufferId NodeLinkMemory::AllocateNewBufferId() {
-  return BufferId{
-      primary_buffer_.next_buffer_id.fetch_add(1, std::memory_order_relaxed)};
+  return BufferId{primary_buffer_.header.next_buffer_id.fetch_add(
+      1, std::memory_order_relaxed)};
 }
 
 SublinkId NodeLinkMemory::AllocateSublinkIds(size_t count) {
-  return SublinkId{primary_buffer_.next_sublink_id.fetch_add(
+  return SublinkId{primary_buffer_.header.next_sublink_id.fetch_add(
       count, std::memory_order_relaxed)};
 }
 
diff --git a/third_party/ipcz/src/ipcz/node_link_memory.h b/third_party/ipcz/src/ipcz/node_link_memory.h
index b4d65a6c..014a78ef 100644
--- a/third_party/ipcz/src/ipcz/node_link_memory.h
+++ b/third_party/ipcz/src/ipcz/node_link_memory.h
@@ -63,7 +63,7 @@
   // Exposes the underlying BufferPool which owns all shared buffers for this
   // NodeLinkMemory and which facilitates dynamic allocation of the fragments
   // within.
-  BufferPool& buffer_pool();
+  BufferPool& buffer_pool() { return buffer_pool_; }
 
   // Returns a new BufferId which should still be unused by any buffer in this
   // NodeLinkMemory's BufferPool, or that of its peer NodeLinkMemory. When
diff --git a/third_party/ipcz/src/ipcz/ref_counted_fragment.cc b/third_party/ipcz/src/ipcz/ref_counted_fragment.cc
new file mode 100644
index 0000000..14b21cf
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/ref_counted_fragment.cc
@@ -0,0 +1,23 @@
+// 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 "ipcz/ref_counted_fragment.h"
+
+#include "third_party/abseil-cpp/absl/base/macros.h"
+
+namespace ipcz {
+
+RefCountedFragment::RefCountedFragment() = default;
+
+RefCountedFragment::~RefCountedFragment() = default;
+
+void RefCountedFragment::AddRef() {
+  ref_count_.fetch_add(1, std::memory_order_relaxed);
+}
+
+int32_t RefCountedFragment::ReleaseRef() {
+  return ref_count_.fetch_sub(1, std::memory_order_acq_rel);
+}
+
+}  // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/ref_counted_fragment.h b/third_party/ipcz/src/ipcz/ref_counted_fragment.h
new file mode 100644
index 0000000..ff69c45
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/ref_counted_fragment.h
@@ -0,0 +1,41 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
+#define IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
+
+#include <atomic>
+
+#include "ipcz/ipcz.h"
+#include "util/ref_counted.h"
+
+namespace ipcz {
+
+// A RefCountedFragment is an object allocated within a shared Fragment from
+// NodeLinkMemory, and which is automatially freed when its last reference is
+// released. Consumers can hold onto references to RefCountedFragment objects
+// by holding a FragmentRef.
+struct IPCZ_ALIGN(4) RefCountedFragment {
+  enum { kAdoptExistingRef };
+  enum { kUnmanagedRef };
+
+  RefCountedFragment();
+  ~RefCountedFragment();
+
+  int32_t ref_count_for_testing() const { return ref_count_; }
+
+  // Increments the reference count for this object.
+  void AddRef();
+
+  // Releases a reference and returns the previous reference count. If this
+  // returns 1, the underlying Fragment can be safely freed.
+  int32_t ReleaseRef();
+
+ private:
+  std::atomic<int32_t> ref_count_{1};
+};
+
+}  // namespace ipcz
+
+#endif  // IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
diff --git a/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
new file mode 100644
index 0000000..5bb0db4
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
@@ -0,0 +1,179 @@
+// 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 "ipcz/ref_counted_fragment.h"
+
+#include <atomic>
+#include <tuple>
+
+#include "ipcz/fragment.h"
+#include "ipcz/fragment_ref.h"
+#include "ipcz/node.h"
+#include "ipcz/node_link_memory.h"
+#include "reference_drivers/sync_reference_driver.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "util/ref_counted.h"
+
+namespace ipcz {
+namespace {
+
+const IpczDriver& kTestDriver = reference_drivers::kSyncReferenceDriver;
+
+using RefCountedFragmentTest = testing::Test;
+
+using TestObject = RefCountedFragment;
+
+TEST_F(RefCountedFragmentTest, NullRef) {
+  FragmentRef<TestObject> ref;
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+
+  ref.reset();
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+
+  FragmentRef<TestObject> other1 = ref;
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+  EXPECT_TRUE(other1.is_null());
+  EXPECT_FALSE(other1.is_addressable());
+
+  FragmentRef<TestObject> other2 = std::move(ref);
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+  EXPECT_TRUE(other2.is_null());
+  EXPECT_FALSE(other2.is_addressable());
+
+  ref = other1;
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+  EXPECT_TRUE(other1.is_null());
+  EXPECT_FALSE(other1.is_addressable());
+
+  ref = std::move(other2);
+  EXPECT_TRUE(ref.is_null());
+  EXPECT_FALSE(ref.is_addressable());
+  EXPECT_TRUE(other1.is_null());
+  EXPECT_FALSE(other1.is_addressable());
+}
+
+TEST_F(RefCountedFragmentTest, SimpleRef) {
+  TestObject object;
+
+  FragmentRef<TestObject> ref(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object));
+  EXPECT_EQ(1, object.ref_count_for_testing());
+  ref.reset();
+  EXPECT_EQ(0, object.ref_count_for_testing());
+}
+
+TEST_F(RefCountedFragmentTest, Copy) {
+  TestObject object1;
+
+  FragmentRef<TestObject> ref1(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object1));
+  EXPECT_EQ(1, object1.ref_count_for_testing());
+
+  FragmentRef<TestObject> other1 = ref1;
+  EXPECT_EQ(2, object1.ref_count_for_testing());
+  other1.reset();
+  EXPECT_EQ(1, object1.ref_count_for_testing());
+  EXPECT_TRUE(other1.is_null());
+  EXPECT_FALSE(other1.is_addressable());
+
+  TestObject object2;
+  auto ref2 = FragmentRef<TestObject>(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object2));
+  EXPECT_EQ(1, object1.ref_count_for_testing());
+  EXPECT_EQ(1, object2.ref_count_for_testing());
+  ref2 = ref1;
+  EXPECT_EQ(2, object1.ref_count_for_testing());
+  EXPECT_EQ(0, object2.ref_count_for_testing());
+  EXPECT_FALSE(ref1.is_null());
+  EXPECT_TRUE(ref1.is_addressable());
+  EXPECT_FALSE(ref2.is_null());
+  EXPECT_TRUE(ref2.is_addressable());
+  ref1.reset();
+  EXPECT_EQ(1, object1.ref_count_for_testing());
+  EXPECT_EQ(0, object2.ref_count_for_testing());
+  EXPECT_TRUE(ref1.is_null());
+  EXPECT_FALSE(ref1.is_addressable());
+  ref2.reset();
+  EXPECT_EQ(0, object1.ref_count_for_testing());
+  EXPECT_EQ(0, object2.ref_count_for_testing());
+  EXPECT_TRUE(ref2.is_null());
+  EXPECT_FALSE(ref2.is_addressable());
+}
+
+TEST_F(RefCountedFragmentTest, Move) {
+  TestObject object1;
+
+  FragmentRef<TestObject> ref1(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object1));
+  EXPECT_EQ(1, ref1.ref_count_for_testing());
+
+  FragmentRef<TestObject> other1 = std::move(ref1);
+  EXPECT_EQ(1, object1.ref_count_for_testing());
+  EXPECT_FALSE(other1.is_null());
+  EXPECT_TRUE(other1.is_addressable());
+  EXPECT_TRUE(ref1.is_null());
+  EXPECT_FALSE(ref1.is_addressable());
+  other1.reset();
+  EXPECT_TRUE(other1.is_null());
+  EXPECT_FALSE(other1.is_addressable());
+  EXPECT_EQ(0, object1.ref_count_for_testing());
+
+  TestObject object2;
+  TestObject object3;
+  FragmentRef<TestObject> ref2(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object2));
+  FragmentRef<TestObject> ref3(
+      RefCountedFragment::kUnmanagedRef,
+      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object3));
+
+  EXPECT_FALSE(ref2.is_null());
+  EXPECT_TRUE(ref2.is_addressable());
+  EXPECT_FALSE(ref3.is_null());
+  EXPECT_TRUE(ref3.is_addressable());
+  EXPECT_EQ(1, object2.ref_count_for_testing());
+  EXPECT_EQ(1, object3.ref_count_for_testing());
+  ref3 = std::move(ref2);
+  EXPECT_EQ(1, object2.ref_count_for_testing());
+  EXPECT_EQ(0, object3.ref_count_for_testing());
+  EXPECT_TRUE(ref2.is_null());
+  EXPECT_FALSE(ref2.is_addressable());
+  EXPECT_FALSE(ref3.is_null());
+  EXPECT_TRUE(ref3.is_addressable());
+  ref3.reset();
+  EXPECT_TRUE(ref3.is_null());
+  EXPECT_FALSE(ref3.is_addressable());
+  EXPECT_EQ(0, object2.ref_count_for_testing());
+  EXPECT_EQ(0, object3.ref_count_for_testing());
+}
+
+TEST_F(RefCountedFragmentTest, Free) {
+  auto node = MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver,
+                                   IPCZ_INVALID_DRIVER_HANDLE);
+  auto memory = NodeLinkMemory::Allocate(std::move(node)).node_link_memory;
+
+  // Allocate a ton of fragments and let them be released by FragmentRef on
+  // destruction. If the fragments aren't freed properly, allocations will fail
+  // and so will the test.
+  constexpr size_t kNumAllocations = 100000;
+  for (size_t i = 0; i < kNumAllocations; ++i) {
+    Fragment fragment =
+        memory->buffer_pool().AllocateFragment(sizeof(TestObject));
+    EXPECT_TRUE(fragment.is_addressable());
+    FragmentRef<TestObject> ref(RefCountedFragment::kAdoptExistingRef, memory,
+                                fragment);
+  }
+}
+
+}  // namespace
+}  // namespace ipcz
diff --git a/third_party/material_web_components/components-chromium/node_modules/.package-lock.json b/third_party/material_web_components/components-chromium/node_modules/.package-lock.json
index c05d7e7..0de8b43 100644
--- a/third_party/material_web_components/components-chromium/node_modules/.package-lock.json
+++ b/third_party/material_web_components/components-chromium/node_modules/.package-lock.json
@@ -5,115 +5,115 @@
   "requires": true,
   "packages": {
     "node_modules/@lit/reactive-element": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.2.tgz",
-      "integrity": "sha512-A2e18XzPMrIh35nhIdE4uoqRzoIpEU5vZYuQN4S3Ee1zkGdYC27DP12pewbw/RLgPHzaE4kx/YqxMzebOpm0dA=="
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.3.tgz",
+      "integrity": "sha512-ukelZ49tzUqgOAEbVujl/U62JNK3wdn5kKtXVqrjKND4QvHACZOMOYaZI6/5Jd8vsg+Fq9HDwiib70FBLydOiQ=="
     },
     "node_modules/@material/animation": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz",
-      "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-GBuR4VmcTQW1D0lPXEosf5Giho72LLbyGIydWGtaEUtLJoive/D9kFkwTN4Fsyt9Kkl7hbhs35vrNe6QkAH4/Q==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/base": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz",
-      "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-UJKbXwZtkrA3sfQDmj8Zbw1Q3Tqtl6KdfVFws95Yf7TCUgTFzbZI/FSx1w7dVugQPOEnIBuZnzqZam/MtHkx4w==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/dom": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz",
-      "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-aR+rfncF6oi2ivdOlKSJI4UXwNzWV5rXM88MLDoSJF1D7lXxhAKhge+tMUBodWGV/q0+FnXLuVAa0WYTrKjo+A==",
       "dependencies": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/feature-targeting": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz",
-      "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-fn7Af3PRyARtNeYqtjxXmE3Y/dCpnpQVWWys57MqiGR/nvc6qpgOfJ6rOdcu/MrOysOE/oebTUDmDnTmwpe9Hw==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/mwc-base": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.0.tgz",
-      "integrity": "sha512-G2xJQ667OzSieXw3IJzRrjDsngfCOnlVPCkl7TnmCThWziTgQISX6kHOEXPYEXwnJmZZrXcxaoc+aeC5cv+nxQ==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.1.tgz",
+      "integrity": "sha512-YcVvWwSoDwQAxjvYevhZgtyXIIPuMeTnw9MtEj+Hv7NJizT88hoTsPmKpwM+X58cIY2SPo0y/tHfgmblWntibQ==",
       "dependencies": {
-        "@material/base": "=14.0.0",
-        "@material/dom": "=14.0.0",
+        "@material/base": "=14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-button": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.0.tgz",
-      "integrity": "sha512-tRO/uSiajvCSR5YVDSoFC6kPCt2okttYOvAfyVkljgNtnhORekcitgKFNQq6JBN2uvD6s/svJXlW7Xv0j/XCQA==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.1.tgz",
+      "integrity": "sha512-ptgAmg50k+71M6ynfv6QeNaBnX7X/EAnhOjxZqhDHrKwZcFuuQyFJJ6r4ypjc21eCSPS7o6xRqJyI4PPpf3xkA==",
       "dependencies": {
-        "@material/mwc-icon": "^0.26.0",
-        "@material/mwc-ripple": "^0.26.0",
+        "@material/mwc-icon": "^0.26.1",
+        "@material/mwc-ripple": "^0.26.1",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-icon": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.0.tgz",
-      "integrity": "sha512-snI+u1xru4Q9FwEXhVxUoVjY3zvZ+H2ezYZa8Zn3OLArRcuz6R4yDxp1CZelaxTwyK2Sb6Hsp0h3liPCc2zl6A==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.1.tgz",
+      "integrity": "sha512-RPcVPn+5p6hA2HjX/0wkeHQuxkJKgXMg47ffw+vhIw28qM8mprSv13hpUgrghb0f7xBvuPhf/kLb37V4xkRfwg==",
       "dependencies": {
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-ripple": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.0.tgz",
-      "integrity": "sha512-unDFbwhZiqojOLF20/5MnYghBk1V1H1r7mJbXG7Jam8x/V1nbdljPIXj0EP3YInt5dBPQHKcf+JkW1En1LGNFw==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.1.tgz",
+      "integrity": "sha512-hBeC2S7TSYLmHetXbtu52/EZFzvAqrQk5skIV0aUZeZvywTJWRVoc5OavDjsJYuKxDnSECMnkIt8+l8WC48chg==",
       "dependencies": {
-        "@material/dom": "=14.0.0",
-        "@material/mwc-base": "^0.26.0",
-        "@material/ripple": "=14.0.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
+        "@material/mwc-base": "^0.26.1",
+        "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/ripple": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz",
-      "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-6g2G62vd8DsMuIUSXlRrzb98qkZ4o8ZREknNwNP2zaLQEOkJ//4j9HaqDt98/3LIjUTY9UIVFTQENiMmlwKHYQ==",
       "dependencies": {
-        "@material/animation": "^14.0.0",
-        "@material/base": "^14.0.0",
-        "@material/dom": "^14.0.0",
-        "@material/feature-targeting": "^14.0.0",
-        "@material/rtl": "^14.0.0",
-        "@material/theme": "^14.0.0",
+        "@material/animation": "14.0.0-canary.53b3cad2f.0",
+        "@material/base": "14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "14.0.0-canary.53b3cad2f.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
+        "@material/rtl": "14.0.0-canary.53b3cad2f.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/rtl": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz",
-      "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-f08LT0HSa0WYU+4Jz/tbm1TQ9Fcf2k+H6dPPYv0J1sZmX6hMgCEmNiUdUFLQFvszoXx2XrRi1/hIFjbz2e69Yg==",
       "dependencies": {
-        "@material/theme": "^14.0.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/theme": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz",
-      "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-S06XAevDCDWMe+GgsEpITMS07imUidzadNaTbJsqssFajBLr53QWVZsG84BpjXKXoYvyEJvb0hX5U0lq6ip9UQ==",
       "dependencies": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
@@ -123,9 +123,9 @@
       "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
     },
     "node_modules/lit": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.3.tgz",
-      "integrity": "sha512-5/v+r9dH3Pw/o0rhp/qYk3ERvOUclNF31bWb0FiW6MPgwdQIr+/KCt/p3zcd8aPl8lIGnxdGrVcZA+gWS6oFOQ==",
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.7.tgz",
+      "integrity": "sha512-WXYujlKFwme5ZqXOZoWuRVZQAwy7scbcVT3wCbAOHefOxyscqjywWGlF2e6nnC9E64yP9l2ZQlN8wZcRlrjUMQ==",
       "dependencies": {
         "@lit/reactive-element": "^1.3.0",
         "lit-element": "^3.2.0",
@@ -133,18 +133,18 @@
       }
     },
     "node_modules/lit-element": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
-      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.1.tgz",
+      "integrity": "sha512-2PxyE9Yq9Jyo/YBK2anycaHcqo93YvB5D+24JxloPVqryW/BOXekne+jGsm0Ke3E5E2v7CDgkmpEmCAzYfrHCQ==",
       "dependencies": {
         "@lit/reactive-element": "^1.3.0",
         "lit-html": "^2.2.0"
       }
     },
     "node_modules/lit-html": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.3.tgz",
-      "integrity": "sha512-vI4j3eWwtQaR8q/O63juZVliBIFMio716X719/lSsGH4UWPy2/7Qf377jsNs4cx3gCHgIbx8yxFgXFQ/igZyXQ==",
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.6.tgz",
+      "integrity": "sha512-xOKsPmq/RAKJ6dUeOxhmOYFjcjf0Q7aSdfBJgdJkOfCUnkmmJPxNrlZpRBeVe1Gg50oYWMlgm6ccAE/SpJgSdw==",
       "dependencies": {
         "@types/trusted-types": "^2.0.2"
       }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.d.ts b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.d.ts
index 1c8b27c2..881ab4f4 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.d.ts
@@ -30,6 +30,8 @@
 export declare class CSSResult {
     ['_$cssResult$']: boolean;
     readonly cssText: string;
+    private _styleSheet?;
+    private _strings;
     private constructor();
     get styleSheet(): CSSStyleSheet | undefined;
     toString(): string;
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.js b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.js
index ee47ea5b..525415f 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.js
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/css-tag.js
@@ -3,5 +3,5 @@
  * Copyright 2019 Google LLC
  * SPDX-License-Identifier: BSD-3-Clause
  */
-const t=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,e=Symbol(),n=new Map;class s{constructor(t,n){if(this._$cssResult$=!0,n!==e)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t}get styleSheet(){let e=n.get(this.cssText);return t&&void 0===e&&(n.set(this.cssText,e=new CSSStyleSheet),e.replaceSync(this.cssText)),e}toString(){return this.cssText}}const o=t=>new s("string"==typeof t?t:t+"",e),r=(t,...n)=>{const o=1===t.length?t[0]:n.reduce(((e,n,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(n)+t[s+1]),t[0]);return new s(o,e)},i=(e,n)=>{t?e.adoptedStyleSheets=n.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet)):n.forEach((t=>{const n=document.createElement("style"),s=window.litNonce;void 0!==s&&n.setAttribute("nonce",s),n.textContent=t.cssText,e.appendChild(n)}))},S=t?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const n of t.cssRules)e+=n.cssText;return o(e)})(t):t;export{s as CSSResult,i as adoptStyles,r as css,S as getCompatibleStyle,t as supportsAdoptingStyleSheets,o as unsafeCSS};
+const t=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,e=Symbol(),n=new WeakMap;class s{constructor(t,n,s){if(this._$cssResult$=!0,s!==e)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=n}get styleSheet(){let e=this.o;const s=this.t;if(t&&void 0===e){const t=void 0!==s&&1===s.length;t&&(e=n.get(s)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(s,e))}return e}toString(){return this.cssText}}const o=t=>new s("string"==typeof t?t:t+"",void 0,e),r=(t,...n)=>{const o=1===t.length?t[0]:n.reduce(((e,n,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(n)+t[s+1]),t[0]);return new s(o,t,e)},i=(e,n)=>{t?e.adoptedStyleSheets=n.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet)):n.forEach((t=>{const n=document.createElement("style"),s=window.litNonce;void 0!==s&&n.setAttribute("nonce",s),n.textContent=t.cssText,e.appendChild(n)}))},S=t?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const n of t.cssRules)e+=n.cssText;return o(e)})(t):t;export{s as CSSResult,i as adoptStyles,r as css,S as getCompatibleStyle,t as supportsAdoptingStyleSheets,o as unsafeCSS};
 //# sourceMappingURL=css-tag.js.map
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/base.d.ts b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/base.d.ts
index f175e1a6..a7a4043 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/base.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/base.d.ts
@@ -44,5 +44,5 @@
 export declare const decorateProperty: ({ finisher, descriptor, }: {
     finisher?: ((ctor: typeof ReactiveElement, property: PropertyKey) => void) | null | undefined;
     descriptor?: ((property: PropertyKey) => PropertyDescriptor) | undefined;
-}) => (protoOrDescriptor: ReactiveElement | ClassElement, name?: PropertyKey | undefined) => void | any;
+}) => (protoOrDescriptor: ReactiveElement | ClassElement, name?: PropertyKey) => void | any;
 //# sourceMappingURL=base.d.ts.map
\ No newline at end of file
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/property.d.ts b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/property.d.ts
index 98b20e8..81141764 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/property.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/decorators/property.d.ts
@@ -37,5 +37,5 @@
  * @category Decorator
  * @ExportDecoratedItems
  */
-export declare function property(options?: PropertyDeclaration): (protoOrDescriptor: Object | ClassElement, name?: PropertyKey | undefined) => any;
+export declare function property(options?: PropertyDeclaration): (protoOrDescriptor: Object | ClassElement, name?: PropertyKey) => any;
 //# sourceMappingURL=property.d.ts.map
\ No newline at end of file
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/package.json b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/package.json
index 2bf35b8..576304ab 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@lit/reactive-element",
-  "version": "1.3.2",
+  "version": "1.3.3",
   "publishConfig": {
     "access": "public"
   },
@@ -79,23 +79,136 @@
     }
   },
   "scripts": {
-    "build": "npm run clean && npm run build:ts && rollup -c && npm run build:babel",
-    "build:watch": "rollup -c --watch",
-    "build:ts": "tsc --build && treemirror development . '**/*.d.ts{,.map}'",
-    "build:ts:watch": "tsc --build --watch",
-    "build:babel": "babel --extensions '.ts' src/test/decorators  --out-dir development/test/decorators-babel",
-    "check-version": "node scripts/check-version-tracker.js",
-    "checksize": "rollup -c --environment=CHECKSIZE",
-    "clean": "rm -rf {css-tag,decorators,polyfill-support,reactive-controller,reactive-element}.{js,js.map,d.ts} test/ decorators/ development/ *.tsbuildinfo",
-    "dev": "scripts/dev.sh",
+    "build": "wireit",
+    "build:ts": "wireit",
+    "build:ts:types": "wireit",
+    "build:rollup": "wireit",
+    "build:babel": "wireit",
+    "check-version": "wireit",
+    "checksize": "wireit",
     "prepublishOnly": "npm run check-version",
-    "publish-dev": "npm test && VERSION=${npm_package_version%-*}-dev.`git rev-parse --short HEAD` && npm version --no-git-tag-version $VERSION && npm publish --tag dev",
-    "regen-package-lock": "rm -rf node_modules package-lock.json; npm install",
-    "test": "npm run test:dev && npm run test:prod",
-    "test:dev": "cd ../tests && npx wtr '../reactive-element/development/**/*_test.(js|html)'",
-    "test:prod": "MODE=prod npm run test:dev",
-    "test:prod:watch": "MODE=prod npm run test:dev -- --watch",
-    "test:watch": "npm run test:dev -- --watch"
+    "test": "wireit",
+    "test:dev": "wireit",
+    "test:prod": "wireit"
+  },
+  "wireit": {
+    "build": {
+      "dependencies": [
+        "build:rollup",
+        "build:babel",
+        "build:ts",
+        "build:ts:types"
+      ]
+    },
+    "build:ts": {
+      "#comment": "Note this also builds polyfill-support via a TypeScript project reference.",
+      "command": "tsc --build --pretty",
+      "clean": "if-file-deleted",
+      "files": [
+        "src/**/*.ts",
+        "tsconfig.json",
+        "tsconfig.polyfill-support.json"
+      ],
+      "output": [
+        "development/**/*.{js,js.map,d.ts,d.ts.map}",
+        "!development/test/decorators-babel",
+        "tsconfig.tsbuildinfo",
+        "tsconfig.polyfill-support.tsbuildinfo"
+      ]
+    },
+    "build:ts:types": {
+      "command": "treemirror development . \"**/*.d.ts{,.map}\"",
+      "dependencies": [
+        "../internal-scripts:build",
+        "build:ts"
+      ],
+      "files": [],
+      "output": [
+        "*.d.ts{,.map}",
+        "decorators/*.d.ts{,.map}"
+      ]
+    },
+    "build:rollup": {
+      "command": "rollup -c",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js",
+        "src/test/*_test.html",
+        "src/test/polyfill-support/*_test.html"
+      ],
+      "output": [
+        "css-tag.js{,.map}",
+        "decorators.js{,.map}",
+        "polyfill-support.js{,.map}",
+        "reactive-controller.js{,.map}",
+        "reactive-element.js{,.map}",
+        "decorators/*.js{,.map}",
+        "test/*_test.html",
+        "development/test/*_test.html",
+        "test/polyfill-support/*_test.html",
+        "development/test/polyfill-support/*_test.html"
+      ]
+    },
+    "build:babel": {
+      "command": "babel --extensions .ts src/test/decorators --out-dir development/test/decorators-babel",
+      "files": [
+        "src/test/decorators/**/*.ts"
+      ],
+      "output": [
+        "development/test/decorators-babel"
+      ]
+    },
+    "checksize": {
+      "command": "rollup -c --environment=CHECKSIZE",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": []
+    },
+    "check-version": {
+      "command": "node scripts/check-version-tracker.js",
+      "files": [
+        "scripts/check-version-tracker.js",
+        "package.json",
+        "src/reactive-element.ts"
+      ],
+      "output": []
+    },
+    "test": {
+      "dependencies": [
+        "test:dev",
+        "test:prod",
+        "check-version"
+      ]
+    },
+    "test:dev": {
+      "command": "MODE=dev node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "build:babel",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    },
+    "test:prod": {
+      "command": "MODE=prod node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "build:rollup",
+        "build:babel",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    }
   },
   "files": [
     "/css-tag.{d.ts,d.ts.map,js,js.map}",
@@ -120,7 +233,7 @@
     "@webcomponents/template": "^1.4.4",
     "@webcomponents/webcomponentsjs": "^2.6.0",
     "chokidar-cli": "^3.0.0",
-    "internal-scripts": "^1.0.0",
+    "@lit-internal/scripts": "^1.0.0",
     "mocha": "^9.1.1",
     "rollup": "^2.70.2",
     "typescript": "^4.3.5"
diff --git a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/reactive-element.js b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/reactive-element.js
index d5169f7..3a6236c 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/reactive-element.js
+++ b/third_party/material_web_components/components-chromium/node_modules/@lit/reactive-element/reactive-element.js
@@ -3,5 +3,5 @@
  * @license
  * Copyright 2017 Google LLC
  * SPDX-License-Identifier: BSD-3-Clause
- */var s;const e=window.trustedTypes,r=e?e.emptyScript:"",h=window.reactiveElementPolyfillSupport,o={toAttribute(t,i){switch(i){case Boolean:t=t?r:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,i){let s=t;switch(i){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t)}catch(t){s=null}}return s}},n=(t,i)=>i!==t&&(i==i||t==t),l={attribute:!0,type:String,converter:o,reflect:!1,hasChanged:n};class a extends HTMLElement{constructor(){super(),this._$Et=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Ei=null,this.o()}static addInitializer(t){var i;null!==(i=this.l)&&void 0!==i||(this.l=[]),this.l.push(t)}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((i,s)=>{const e=this._$Eh(s,i);void 0!==e&&(this._$Eu.set(e,s),t.push(e))})),t}static createProperty(t,i=l){if(i.state&&(i.attribute=!1),this.finalize(),this.elementProperties.set(t,i),!i.noAccessor&&!this.prototype.hasOwnProperty(t)){const s="symbol"==typeof t?Symbol():"__"+t,e=this.getPropertyDescriptor(t,s,i);void 0!==e&&Object.defineProperty(this.prototype,t,e)}}static getPropertyDescriptor(t,i,s){return{get(){return this[i]},set(e){const r=this[t];this[i]=e,this.requestUpdate(t,r,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||l}static finalize(){if(this.hasOwnProperty("finalized"))return!1;this.finalized=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),this.elementProperties=new Map(t.elementProperties),this._$Eu=new Map,this.hasOwnProperty("properties")){const t=this.properties,i=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const s of i)this.createProperty(s,t[s])}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(i){const s=[];if(Array.isArray(i)){const e=new Set(i.flat(1/0).reverse());for(const i of e)s.unshift(t(i))}else void 0!==i&&s.push(t(i));return s}static _$Eh(t,i){const s=i.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}o(){var t;this._$Ep=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Em(),this.requestUpdate(),null===(t=this.constructor.l)||void 0===t||t.forEach((t=>t(this)))}addController(t){var i,s;(null!==(i=this._$Eg)&&void 0!==i?i:this._$Eg=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(s=t.hostConnected)||void 0===s||s.call(t))}removeController(t){var i;null===(i=this._$Eg)||void 0===i||i.splice(this._$Eg.indexOf(t)>>>0,1)}_$Em(){this.constructor.elementProperties.forEach(((t,i)=>{this.hasOwnProperty(i)&&(this._$Et.set(i,this[i]),delete this[i])}))}createRenderRoot(){var t;const s=null!==(t=this.shadowRoot)&&void 0!==t?t:this.attachShadow(this.constructor.shadowRootOptions);return i(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$Eg)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostConnected)||void 0===i?void 0:i.call(t)}))}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$Eg)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostDisconnected)||void 0===i?void 0:i.call(t)}))}attributeChangedCallback(t,i,s){this._$AK(t,s)}_$ES(t,i,s=l){var e,r;const h=this.constructor._$Eh(t,s);if(void 0!==h&&!0===s.reflect){const n=(null!==(r=null===(e=s.converter)||void 0===e?void 0:e.toAttribute)&&void 0!==r?r:o.toAttribute)(i,s.type);this._$Ei=t,null==n?this.removeAttribute(h):this.setAttribute(h,n),this._$Ei=null}}_$AK(t,i){var s,e,r;const h=this.constructor,n=h._$Eu.get(t);if(void 0!==n&&this._$Ei!==n){const t=h.getPropertyOptions(n),l=t.converter,a=null!==(r=null!==(e=null===(s=l)||void 0===s?void 0:s.fromAttribute)&&void 0!==e?e:"function"==typeof l?l:null)&&void 0!==r?r:o.fromAttribute;this._$Ei=n,this[n]=a(i,t.type),this._$Ei=null}}requestUpdate(t,i,s){let e=!0;void 0!==t&&(((s=s||this.constructor.getPropertyOptions(t)).hasChanged||n)(this[t],i)?(this._$AL.has(t)||this._$AL.set(t,i),!0===s.reflect&&this._$Ei!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,s))):e=!1),!this.isUpdatePending&&e&&(this._$Ep=this._$E_())}async _$E_(){this.isUpdatePending=!0;try{await this._$Ep}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this.hasUpdated,this._$Et&&(this._$Et.forEach(((t,i)=>this[i]=t)),this._$Et=void 0);let i=!1;const s=this._$AL;try{i=this.shouldUpdate(s),i?(this.willUpdate(s),null===(t=this._$Eg)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostUpdate)||void 0===i?void 0:i.call(t)})),this.update(s)):this._$EU()}catch(t){throw i=!1,this._$EU(),t}i&&this._$AE(s)}willUpdate(t){}_$AE(t){var i;null===(i=this._$Eg)||void 0===i||i.forEach((t=>{var i;return null===(i=t.hostUpdated)||void 0===i?void 0:i.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EU(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$Ep}shouldUpdate(t){return!0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,i)=>this._$ES(i,this[i],t))),this._$EC=void 0),this._$EU()}updated(t){}firstUpdated(t){}}a.finalized=!0,a.elementProperties=new Map,a.elementStyles=[],a.shadowRootOptions={mode:"open"},null==h||h({ReactiveElement:a}),(null!==(s=globalThis.reactiveElementVersions)&&void 0!==s?s:globalThis.reactiveElementVersions=[]).push("1.3.2");export{a as ReactiveElement,o as defaultConverter,n as notEqual};
+ */var s;const e=window.trustedTypes,r=e?e.emptyScript:"",h=window.reactiveElementPolyfillSupport,o={toAttribute(t,i){switch(i){case Boolean:t=t?r:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,i){let s=t;switch(i){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t)}catch(t){s=null}}return s}},n=(t,i)=>i!==t&&(i==i||t==t),l={attribute:!0,type:String,converter:o,reflect:!1,hasChanged:n};class a extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this.u()}static addInitializer(t){var i;null!==(i=this.h)&&void 0!==i||(this.h=[]),this.h.push(t)}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((i,s)=>{const e=this._$Ep(s,i);void 0!==e&&(this._$Ev.set(e,s),t.push(e))})),t}static createProperty(t,i=l){if(i.state&&(i.attribute=!1),this.finalize(),this.elementProperties.set(t,i),!i.noAccessor&&!this.prototype.hasOwnProperty(t)){const s="symbol"==typeof t?Symbol():"__"+t,e=this.getPropertyDescriptor(t,s,i);void 0!==e&&Object.defineProperty(this.prototype,t,e)}}static getPropertyDescriptor(t,i,s){return{get(){return this[i]},set(e){const r=this[t];this[i]=e,this.requestUpdate(t,r,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||l}static finalize(){if(this.hasOwnProperty("finalized"))return!1;this.finalized=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),this.elementProperties=new Map(t.elementProperties),this._$Ev=new Map,this.hasOwnProperty("properties")){const t=this.properties,i=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const s of i)this.createProperty(s,t[s])}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(i){const s=[];if(Array.isArray(i)){const e=new Set(i.flat(1/0).reverse());for(const i of e)s.unshift(t(i))}else void 0!==i&&s.push(t(i));return s}static _$Ep(t,i){const s=i.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}u(){var t;this._$E_=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Eg(),this.requestUpdate(),null===(t=this.constructor.h)||void 0===t||t.forEach((t=>t(this)))}addController(t){var i,s;(null!==(i=this._$ES)&&void 0!==i?i:this._$ES=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(s=t.hostConnected)||void 0===s||s.call(t))}removeController(t){var i;null===(i=this._$ES)||void 0===i||i.splice(this._$ES.indexOf(t)>>>0,1)}_$Eg(){this.constructor.elementProperties.forEach(((t,i)=>{this.hasOwnProperty(i)&&(this._$Ei.set(i,this[i]),delete this[i])}))}createRenderRoot(){var t;const s=null!==(t=this.shadowRoot)&&void 0!==t?t:this.attachShadow(this.constructor.shadowRootOptions);return i(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostConnected)||void 0===i?void 0:i.call(t)}))}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostDisconnected)||void 0===i?void 0:i.call(t)}))}attributeChangedCallback(t,i,s){this._$AK(t,s)}_$EO(t,i,s=l){var e,r;const h=this.constructor._$Ep(t,s);if(void 0!==h&&!0===s.reflect){const n=(null!==(r=null===(e=s.converter)||void 0===e?void 0:e.toAttribute)&&void 0!==r?r:o.toAttribute)(i,s.type);this._$El=t,null==n?this.removeAttribute(h):this.setAttribute(h,n),this._$El=null}}_$AK(t,i){var s,e;const r=this.constructor,h=r._$Ev.get(t);if(void 0!==h&&this._$El!==h){const t=r.getPropertyOptions(h),n=t.converter,l=null!==(e=null!==(s=null==n?void 0:n.fromAttribute)&&void 0!==s?s:"function"==typeof n?n:null)&&void 0!==e?e:o.fromAttribute;this._$El=h,this[h]=l(i,t.type),this._$El=null}}requestUpdate(t,i,s){let e=!0;void 0!==t&&(((s=s||this.constructor.getPropertyOptions(t)).hasChanged||n)(this[t],i)?(this._$AL.has(t)||this._$AL.set(t,i),!0===s.reflect&&this._$El!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,s))):e=!1),!this.isUpdatePending&&e&&(this._$E_=this._$Ej())}async _$Ej(){this.isUpdatePending=!0;try{await this._$E_}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this.hasUpdated,this._$Ei&&(this._$Ei.forEach(((t,i)=>this[i]=t)),this._$Ei=void 0);let i=!1;const s=this._$AL;try{i=this.shouldUpdate(s),i?(this.willUpdate(s),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var i;return null===(i=t.hostUpdate)||void 0===i?void 0:i.call(t)})),this.update(s)):this._$Ek()}catch(t){throw i=!1,this._$Ek(),t}i&&this._$AE(s)}willUpdate(t){}_$AE(t){var i;null===(i=this._$ES)||void 0===i||i.forEach((t=>{var i;return null===(i=t.hostUpdated)||void 0===i?void 0:i.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$Ek(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$E_}shouldUpdate(t){return!0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,i)=>this._$EO(i,this[i],t))),this._$EC=void 0),this._$Ek()}updated(t){}firstUpdated(t){}}a.finalized=!0,a.elementProperties=new Map,a.elementStyles=[],a.shadowRootOptions={mode:"open"},null==h||h({ReactiveElement:a}),(null!==(s=globalThis.reactiveElementVersions)&&void 0!==s?s:globalThis.reactiveElementVersions=[]).push("1.3.3");export{a as ReactiveElement,o as defaultConverter,n as notEqual};
 //# sourceMappingURL=reactive-element.js.map
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/base/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/base/package.json
index 41d7352d8..2b57936 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/base/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/base/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/base",
   "description": "The set of base classes for Material Components for the web",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "main": "dist/mdc.base.js",
   "module": "index.js",
@@ -14,5 +14,5 @@
   "dependencies": {
     "tslib": "^2.1.0"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/dom/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/dom/package.json
index e9894b2..f2082b47 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/dom/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/dom/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/dom",
   "description": "DOM manipulation utilities for Material Components for the web",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "main": "dist/mdc.dom.js",
   "module": "index.js",
@@ -15,8 +15,8 @@
     "access": "public"
   },
   "dependencies": {
-    "@material/feature-targeting": "^14.0.0",
+    "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
     "tslib": "^2.1.0"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/feature-targeting/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/feature-targeting/package.json
index bbd60ec..9ad5aa8 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/feature-targeting/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/feature-targeting/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/feature-targeting",
   "description": "Material Components for the web Feature Targeting Scss helpers",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "keywords": [
     "material components",
@@ -20,5 +20,5 @@
   "publishConfig": {
     "access": "public"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/base-element.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/base-element.d.ts
index e571943..e953111b 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/base-element.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/base-element.d.ts
@@ -3,11 +3,11 @@
  * Copyright 2018 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { MDCFoundation } from '@material/base';
+import { MDCFoundation } from '@material/base/foundation.js';
 import { LitElement } from 'lit';
-import { Constructor } from './utils';
-export { CustomEventListener, EventType, SpecificEventListener } from '@material/base/types';
-export { addHasRemoveClass } from './utils';
+import { Constructor } from './utils.js';
+export { CustomEventListener, EventType, SpecificEventListener } from '@material/base/types.js';
+export { addHasRemoveClass } from './utils.js';
 /** @soyCompatible */
 export declare abstract class BaseElement extends LitElement {
     /**
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/form-element.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/form-element.d.ts
index 0eb21f54..a0db883 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/form-element.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/form-element.d.ts
@@ -3,8 +3,8 @@
  * Copyright 2018 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { addHasRemoveClass, BaseElement, CustomEventListener, EventType, SpecificEventListener } from './base-element';
-import { RippleInterface } from './utils';
+import { addHasRemoveClass, BaseElement, CustomEventListener, EventType, SpecificEventListener } from './base-element.js';
+import { RippleInterface } from './utils.js';
 export { addHasRemoveClass, BaseElement, CustomEventListener, EventType, RippleInterface, SpecificEventListener };
 declare global {
     interface FormDataEvent extends Event {
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/package.json
index f2a8a48..2660dec 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-base/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@material/mwc-base",
-  "version": "0.26.0",
+  "version": "0.26.1",
   "description": "",
   "main": "base-element.js",
   "module": "base-element.js",
@@ -11,19 +11,19 @@
   },
   "license": "Apache-2.0",
   "dependencies": {
-    "@material/base": "=14.0.0",
-    "@material/dom": "=14.0.0",
+    "@material/base": "=14.0.0-canary.53b3cad2f.0",
+    "@material/dom": "=14.0.0-canary.53b3cad2f.0",
     "lit": "^2.0.0",
     "tslib": "^2.0.1"
   },
   "devDependencies": {
-    "@material/elevation": "=14.0.0",
-    "@material/feature-targeting": "=14.0.0",
-    "@material/ripple": "=14.0.0",
-    "@material/theme": "=14.0.0"
+    "@material/elevation": "=14.0.0-canary.53b3cad2f.0",
+    "@material/feature-targeting": "=14.0.0-canary.53b3cad2f.0",
+    "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
+    "@material/theme": "=14.0.0-canary.53b3cad2f.0"
   },
   "publishConfig": {
     "access": "public"
   },
-  "gitHead": "056b3ceffbe2fe3408dbdbb319932da85637e779"
+  "gitHead": "06b516b7f91867acd0cbe5676767aea8f490cbee"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button-base.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button-base.d.ts
index 0e90abf1..aa938a85 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button-base.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button-base.d.ts
@@ -3,13 +3,13 @@
  * Copyright 2019 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import '@material/mwc-icon/mwc-icon';
-import '@material/mwc-ripple/mwc-ripple';
-import { AriaHasPopup } from '@material/mwc-base/aria-property';
-import { Ripple } from '@material/mwc-ripple/mwc-ripple';
-import { RippleHandlers } from '@material/mwc-ripple/ripple-handlers';
+import '@material/mwc-icon/mwc-icon.js';
+import '@material/mwc-ripple/mwc-ripple.js';
+import { AriaHasPopup } from '@material/mwc-base/aria-property.js';
+import { Ripple } from '@material/mwc-ripple/mwc-ripple.js';
+import { RippleHandlers } from '@material/mwc-ripple/ripple-handlers.js';
 import { LitElement, TemplateResult } from 'lit';
-import { ClassInfo } from 'lit/directives/class-map';
+import { ClassInfo } from 'lit/directives/class-map.js';
 /** @soyCompatible */
 export declare class ButtonBase extends LitElement {
     static shadowRootOptions: ShadowRootInit;
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button.d.ts
index e815d307..835e33e4 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/mwc-button.d.ts
@@ -3,7 +3,7 @@
  * Copyright 2018 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { ButtonBase } from './mwc-button-base';
+import { ButtonBase } from './mwc-button-base.js';
 /** @soyCompatible */
 export declare class Button extends ButtonBase {
     static styles: import("lit").CSSResult[];
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/package.json
index 33cdc6e..a032bf7 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-button/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@material/mwc-button",
-  "version": "0.26.0",
+  "version": "0.26.1",
   "description": "Material Design button web component",
   "keywords": [
     "material design",
@@ -16,8 +16,8 @@
   },
   "license": "Apache-2.0",
   "dependencies": {
-    "@material/mwc-icon": "^0.26.0",
-    "@material/mwc-ripple": "^0.26.0",
+    "@material/mwc-icon": "^0.26.1",
+    "@material/mwc-ripple": "^0.26.1",
     "lit": "^2.0.0",
     "tslib": "^2.0.1"
   },
@@ -25,14 +25,14 @@
     "build:style": "node ../../scripts/sass-to-lit-css/index.js styles.scss demo_styles.scss"
   },
   "devDependencies": {
-    "@material/button": "=14.0.0",
-    "@material/elevation": "=14.0.0",
-    "@material/ripple": "=14.0.0",
-    "@material/shape": "=14.0.0",
-    "@material/theme": "=14.0.0"
+    "@material/button": "=14.0.0-canary.53b3cad2f.0",
+    "@material/elevation": "=14.0.0-canary.53b3cad2f.0",
+    "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
+    "@material/shape": "=14.0.0-canary.53b3cad2f.0",
+    "@material/theme": "=14.0.0-canary.53b3cad2f.0"
   },
   "publishConfig": {
     "access": "public"
   },
-  "gitHead": "056b3ceffbe2fe3408dbdbb319932da85637e779"
+  "gitHead": "06b516b7f91867acd0cbe5676767aea8f490cbee"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-icon/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-icon/package.json
index 2c3b47275..37e444b 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-icon/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-icon/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@material/mwc-icon",
-  "version": "0.26.0",
+  "version": "0.26.1",
   "description": "Material Design icon web component",
   "keywords": [
     "material design",
@@ -25,5 +25,5 @@
   "publishConfig": {
     "access": "public"
   },
-  "gitHead": "056b3ceffbe2fe3408dbdbb319932da85637e779"
+  "gitHead": "06b516b7f91867acd0cbe5676767aea8f490cbee"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple-base.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple-base.d.ts
index d1ea11e..1bf2ae6 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple-base.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple-base.d.ts
@@ -3,10 +3,10 @@
  * Copyright 2018 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { BaseElement } from '@material/mwc-base/base-element';
-import { RippleInterface } from '@material/mwc-base/utils';
-import { MDCRippleAdapter } from '@material/ripple/adapter';
-import MDCRippleFoundation from '@material/ripple/foundation';
+import { BaseElement } from '@material/mwc-base/base-element.js';
+import { RippleInterface } from '@material/mwc-base/utils.js';
+import { MDCRippleAdapter } from '@material/ripple/adapter.js';
+import MDCRippleFoundation from '@material/ripple/foundation.js';
 import { PropertyValues, TemplateResult } from 'lit';
 /** @soyCompatible */
 export declare class RippleBase extends BaseElement implements RippleInterface {
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple.d.ts
index 85bdbea3..24ce7ea 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/mwc-ripple.d.ts
@@ -3,7 +3,7 @@
  * Copyright 2018 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { RippleBase } from './mwc-ripple-base';
+import { RippleBase } from './mwc-ripple-base.js';
 declare global {
     interface HTMLElementTagNameMap {
         'mwc-ripple': Ripple;
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/package.json
index cea4a0d..ca2c5e0 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@material/mwc-ripple",
-  "version": "0.26.0",
+  "version": "0.26.1",
   "description": "Material Design ripple web component",
   "keywords": [
     "material design",
@@ -16,14 +16,14 @@
   },
   "license": "Apache-2.0",
   "dependencies": {
-    "@material/dom": "=14.0.0",
-    "@material/mwc-base": "^0.26.0",
-    "@material/ripple": "=14.0.0",
+    "@material/dom": "=14.0.0-canary.53b3cad2f.0",
+    "@material/mwc-base": "^0.26.1",
+    "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
     "lit": "^2.0.0",
     "tslib": "^2.0.1"
   },
   "devDependencies": {
-    "@material/theme": "=14.0.0"
+    "@material/theme": "=14.0.0-canary.53b3cad2f.0"
   },
   "scripts": {
     "build:style": "node ../../scripts/sass-to-lit-css/index.js mwc-ripple.scss"
@@ -31,5 +31,5 @@
   "publishConfig": {
     "access": "public"
   },
-  "gitHead": "056b3ceffbe2fe3408dbdbb319932da85637e779"
+  "gitHead": "06b516b7f91867acd0cbe5676767aea8f490cbee"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/ripple-handlers.d.ts b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/ripple-handlers.d.ts
index b2d0ff6..dc66f76 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/ripple-handlers.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/mwc-ripple/ripple-handlers.d.ts
@@ -3,7 +3,7 @@
  * Copyright 2020 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
-import { RippleInterface } from '@material/mwc-base/utils';
+import { RippleInterface } from '@material/mwc-base/utils.js';
 /**
  * Class that encapsulates the events handlers for `mwc-ripple`
  *
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/ripple/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/ripple/package.json
index 652d41c..b3eee22 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/ripple/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/ripple/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/ripple",
   "description": "The Material Components for the web Ink Ripple effect for web element interactions",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "keywords": [
     "material components",
@@ -17,13 +17,13 @@
     "directory": "packages/mdc-ripple"
   },
   "dependencies": {
-    "@material/animation": "^14.0.0",
-    "@material/base": "^14.0.0",
-    "@material/dom": "^14.0.0",
-    "@material/feature-targeting": "^14.0.0",
-    "@material/rtl": "^14.0.0",
-    "@material/theme": "^14.0.0",
+    "@material/animation": "14.0.0-canary.53b3cad2f.0",
+    "@material/base": "14.0.0-canary.53b3cad2f.0",
+    "@material/dom": "14.0.0-canary.53b3cad2f.0",
+    "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
+    "@material/rtl": "14.0.0-canary.53b3cad2f.0",
+    "@material/theme": "14.0.0-canary.53b3cad2f.0",
     "tslib": "^2.1.0"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/rtl/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/rtl/package.json
index 7920bd7..f61b65e 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/rtl/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/rtl/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/rtl",
   "description": "Material Components for the web RTL Scss helpers",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "keywords": [
     "material components",
@@ -16,8 +16,8 @@
     "directory": "packages/mdc-rtl"
   },
   "dependencies": {
-    "@material/theme": "^14.0.0",
+    "@material/theme": "14.0.0-canary.53b3cad2f.0",
     "tslib": "^2.1.0"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/@material/theme/package.json b/third_party/material_web_components/components-chromium/node_modules/@material/theme/package.json
index 35de66b..a1e0249a 100644
--- a/third_party/material_web_components/components-chromium/node_modules/@material/theme/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/@material/theme/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@material/theme",
   "description": "The Material Components for the web theming system",
-  "version": "14.0.0",
+  "version": "14.0.0-canary.53b3cad2f.0",
   "license": "MIT",
   "keywords": [
     "material components",
@@ -15,8 +15,8 @@
   },
   "sideEffects": false,
   "dependencies": {
-    "@material/feature-targeting": "^14.0.0",
+    "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
     "tslib": "^2.1.0"
   },
-  "gitHead": "432c815e58d61a257742836f816cf95e271e6ea1"
+  "gitHead": "ebeda2e23436103241b0e82afd57b60f74599133"
 }
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-element/lit-element.js b/third_party/material_web_components/components-chromium/node_modules/lit-element/lit-element.js
index 9db9b63f..a521c84 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-element/lit-element.js
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-element/lit-element.js
@@ -3,5 +3,5 @@
  * @license
  * Copyright 2017 Google LLC
  * SPDX-License-Identifier: BSD-3-Clause
- */var l,o;const r=t;class s extends t{constructor(){super(...arguments),this.renderOptions={host:this},this._$Dt=void 0}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Dt=e(i,this.renderRoot,this.renderOptions)}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!0)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Dt)||void 0===t||t.setConnected(!1)}render(){return i}}s.finalized=!0,s._$litElement$=!0,null===(l=globalThis.litElementHydrateSupport)||void 0===l||l.call(globalThis,{LitElement:s});const n=globalThis.litElementPolyfillSupport;null==n||n({LitElement:s});const h={_$AK:(t,e,i)=>{t._$AK(e,i)},_$AL:t=>t._$AL};(null!==(o=globalThis.litElementVersions)&&void 0!==o?o:globalThis.litElementVersions=[]).push("3.2.0");export{s as LitElement,r as UpdatingElement,h as _$LE};
+ */var l,o;const r=t;class s extends t{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const i=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=e(i,this.renderRoot,this.renderOptions)}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!0)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!1)}render(){return i}}s.finalized=!0,s._$litElement$=!0,null===(l=globalThis.litElementHydrateSupport)||void 0===l||l.call(globalThis,{LitElement:s});const n=globalThis.litElementPolyfillSupport;null==n||n({LitElement:s});const h={_$AK:(t,e,i)=>{t._$AK(e,i)},_$AL:t=>t._$AL};(null!==(o=globalThis.litElementVersions)&&void 0!==o?o:globalThis.litElementVersions=[]).push("3.2.1");export{s as LitElement,r as UpdatingElement,h as _$LE};
 //# sourceMappingURL=lit-element.js.map
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-element/package.json b/third_party/material_web_components/components-chromium/node_modules/lit-element/package.json
index eb287b4..fbcc5081 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-element/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-element/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lit-element",
-  "version": "3.2.0",
+  "version": "3.2.1",
   "publishConfig": {
     "access": "public"
   },
@@ -80,24 +80,131 @@
     }
   },
   "scripts": {
-    "build": "npm run clean && npm run build:ts && rollup -c",
-    "build:watch": "rollup -c --watch",
-    "build:bundle": "npm run clean:bundle && tsc --build && rollup -c rollup.bundle.config.js",
-    "build:ts": "tsc --build && treemirror development . '**/*.d.ts{,.map}'",
-    "build:ts:watch": "tsc --build --watch",
-    "check-version": "node scripts/check-version-tracker.js",
-    "checksize": "rollup -c --environment=CHECKSIZE",
-    "clean": "rm -rf {decorators,experimental-hydrate-support,index,lit-element,polyfill-support,private-ssr-support,lit.min}.{js,js.map,d.ts} test/ decorators/ development/ *.tsbuildinfo",
-    "dev": "scripts/dev.sh",
+    "build": "wireit",
+    "build:rollup": "wireit",
+    "build:ts": "wireit",
+    "build:ts:types": "wireit",
+    "check-version": "wireit",
+    "checksize": "wireit",
     "prepublishOnly": "npm run check-version",
-    "publish-dev": "npm test && VERSION=${npm_package_version%-*}-dev.`git rev-parse --short HEAD` && npm version --no-git-tag-version $VERSION && npm publish --tag dev",
-    "regen-package-lock": "rm -rf node_modules package-lock.json; npm install",
-    "release": "np --any-branch --yolo",
-    "test": "npm run test:dev && npm run test:prod",
-    "test:dev": "cd ../tests && npx wtr '../lit-element/development/**/*_test.(js|html)'",
-    "test:prod": "MODE=prod npm run test:dev",
-    "test:prod:watch": "MODE=prod npm run test:dev -- --watch",
-    "test:watch": "npm run test:dev -- --watch"
+    "test": "wireit",
+    "test:dev": "wireit",
+    "test:prod": "wireit"
+  },
+  "wireit": {
+    "build": {
+      "dependencies": [
+        "build:rollup",
+        "build:ts",
+        "build:ts:types",
+        "../lit-html:build",
+        "../reactive-element:build"
+      ]
+    },
+    "build:ts": {
+      "#comment": "Note this also builds polyfill-support via a TypeScript project reference.",
+      "command": "tsc --build --pretty",
+      "clean": "if-file-deleted",
+      "dependencies": [
+        "../lit-html:build:ts:types",
+        "../reactive-element:build:ts:types"
+      ],
+      "files": [
+        "src/**/*.ts",
+        "tsconfig.json",
+        "tsconfig.polyfill-support.json"
+      ],
+      "output": [
+        "development/**/*.{js,js.map,d.ts,d.ts.map}",
+        "tsconfig.tsbuildinfo",
+        "tsconfig.polyfill-support.tsbuildinfo"
+      ]
+    },
+    "build:ts:types": {
+      "command": "treemirror development . \"**/*.d.ts{,.map}\"",
+      "dependencies": [
+        "../internal-scripts:build",
+        "build:ts"
+      ],
+      "files": [],
+      "output": [
+        "*.d.ts{,.map}",
+        "decorators/*.d.ts{,.map}"
+      ]
+    },
+    "build:rollup": {
+      "command": "rollup -c",
+      "dependencies": [
+        "build:ts",
+        "../lit-html:build:rollup",
+        "../reactive-element:build:rollup"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js",
+        "src/test/*_test.html",
+        "src/test/polyfill-support/*_test.html"
+      ],
+      "output": [
+        "decorators.js{,.map}",
+        "experimental-hydrate-support.js{,.map}",
+        "index.js{,.map}",
+        "lit-element.js{,.map}",
+        "polyfill-support.js{,.map}",
+        "private-ssr-support.js{,.map}",
+        "decorators/*.js{,.map}",
+        "test/*_test.html",
+        "development/test/*_test.html",
+        "test/polyfill-support/*_test.html",
+        "development/test/polyfill-support/*_test.html"
+      ]
+    },
+    "checksize": {
+      "command": "rollup -c --environment=CHECKSIZE",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": []
+    },
+    "check-version": {
+      "command": "node scripts/check-version-tracker.js",
+      "files": [
+        "scripts/check-version-tracker.js",
+        "package.json",
+        "src/lit-element.ts"
+      ],
+      "output": []
+    },
+    "test": {
+      "dependencies": [
+        "test:dev",
+        "test:prod",
+        "check-version"
+      ]
+    },
+    "test:dev": {
+      "command": "MODE=dev node ../tests/run-web-tests.js  \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    },
+    "test:prod": {
+      "command": "MODE=prod node ../tests/run-web-tests.js  \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "build:rollup",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    }
   },
   "files": [
     "/decorators.{d.ts,d.ts.map,js,js.map}",
@@ -123,9 +230,9 @@
     "@webcomponents/webcomponentsjs": "^2.6.0",
     "chokidar-cli": "^3.0.0",
     "downlevel-dts": "^0.7.0",
-    "internal-scripts": "^1.0.0",
+    "@lit-internal/scripts": "^1.0.0",
     "mocha": "^9.1.1",
-    "rollup": "^2.26.4",
+    "rollup": "^2.70.2",
     "tslib": "^2.0.3",
     "typescript": "^4.3.5"
   },
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-html/directives/live.d.ts b/third_party/material_web_components/components-chromium/node_modules/lit-html/directives/live.d.ts
index 23d46f2..f472de73 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-html/directives/live.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-html/directives/live.d.ts
@@ -28,7 +28,7 @@
  * html`<input .value=${live(x)}>`
  * ```
  *
- * `live()` performs a strict equality check agains the live DOM value, and if
+ * `live()` performs a strict equality check against the live DOM value, and if
  * the new value is equal to the live value, does nothing. This means that
  * `live()` should not be used when the binding will cause a type conversion. If
  * you use `live()` with an attribute binding, make sure that only strings are
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.d.ts b/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.d.ts
index b5cd5867..a22349b 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.d.ts
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.d.ts
@@ -183,7 +183,17 @@
 declare const ELEMENT_PART = 6;
 declare const COMMENT_PART = 7;
 /**
- * The return type of the template tag functions.
+ * The return type of the template tag functions, {@linkcode html} and
+ * {@linkcode svg}.
+ *
+ * A `TemplateResult` object holds all the information about a template
+ * expression required to render it: the template strings, expression values,
+ * and type of template (html or svg).
+ *
+ * `TemplateResult` objects do not create any DOM on their own. To create or
+ * update DOM you need to render the `TemplateResult`. See
+ * [Rendering](https://lit.dev/docs/components/rendering) for more information.
+ *
  */
 export declare type TemplateResult<T extends ResultType = ResultType> = {
     ['_$litType$']: T;
@@ -301,9 +311,28 @@
 }
 /**
  * Renders a value, usually a lit-html TemplateResult, to the container.
- * @param value
- * @param container
- * @param options
+ *
+ * This example renders the text "Hello, Zoe!" inside a paragraph tag, appending
+ * it to the container `document.body`.
+ *
+ * ```js
+ * import {html, render} from 'lit';
+ *
+ * const name = "Zoe";
+ * render(html`<p>Hello, ${name}!</p>`, document.body);
+ * ```
+ *
+ * @param value Any [renderable
+ *   value](https://lit.dev/docs/templates/expressions/#child-expressions),
+ *   typically a {@linkcode TemplateResult} created by evaluating a template tag
+ *   like {@linkcode html} or {@linkcode svg}.
+ * @param container A DOM container to render to. The first render will append
+ *   the rendered value to the container, and subsequent renders will
+ *   efficiently update the rendered value if the same result type was
+ *   previously rendered there.
+ * @param options See {@linkcode RenderOptions} for options documentation.
+ * @see
+ * {@link https://lit.dev/docs/libraries/standalone-templates/#rendering-lit-html-templates| Rendering Lit HTML Templates}
  */
 export declare const render: {
     (value: unknown, container: HTMLElement | DocumentFragment, options?: RenderOptions | undefined): RootPart;
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.js b/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.js
index 9d7b94b..7062262 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.js
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-html/lit-html.js
@@ -3,5 +3,5 @@
  * Copyright 2017 Google LLC
  * SPDX-License-Identifier: BSD-3-Clause
  */
-var t;const i=globalThis.trustedTypes,s=i?i.createPolicy("lit-html",{createHTML:t=>t}):void 0,e=`lit$${(Math.random()+"").slice(9)}$`,o="?"+e,n=`<${o}>`,l=document,h=(t="")=>l.createComment(t),r=t=>null===t||"object"!=typeof t&&"function"!=typeof t,d=Array.isArray,u=t=>{var i;return d(t)||"function"==typeof(null===(i=t)||void 0===i?void 0:i[Symbol.iterator])},c=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,a=/>/g,f=/>|[ 	\n\r](?:([^\s"'>=/]+)([ 	\n\r]*=[ 	\n\r]*(?:[^ 	\n\r"'`<>=]|("|')|))|$)/g,_=/'/g,m=/"/g,g=/^(?:script|style|textarea|title)$/i,p=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),$=p(1),y=p(2),b=Symbol.for("lit-noChange"),w=Symbol.for("lit-nothing"),T=new WeakMap,x=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new N(i.insertBefore(h(),t),t,void 0,null!=s?s:{})}return l._$AI(t),l},A=l.createTreeWalker(l,129,null,!1),C=(t,i)=>{const o=t.length-1,l=[];let h,r=2===i?"<svg>":"",d=c;for(let i=0;i<o;i++){const s=t[i];let o,u,p=-1,$=0;for(;$<s.length&&(d.lastIndex=$,u=d.exec(s),null!==u);)$=d.lastIndex,d===c?"!--"===u[1]?d=v:void 0!==u[1]?d=a:void 0!==u[2]?(g.test(u[2])&&(h=RegExp("</"+u[2],"g")),d=f):void 0!==u[3]&&(d=f):d===f?">"===u[0]?(d=null!=h?h:c,p=-1):void 0===u[1]?p=-2:(p=d.lastIndex-u[2].length,o=u[1],d=void 0===u[3]?f:'"'===u[3]?m:_):d===m||d===_?d=f:d===v||d===a?d=c:(d=f,h=void 0);const y=d===f&&t[i+1].startsWith("/>")?" ":"";r+=d===c?s+n:p>=0?(l.push(o),s.slice(0,p)+"$lit$"+s.slice(p)+e+y):s+e+(-2===p?(l.push(void 0),i):y)}const u=r+(t[o]||"<?>")+(2===i?"</svg>":"");if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return[void 0!==s?s.createHTML(u):u,l]};class E{constructor({strings:t,_$litType$:s},n){let l;this.parts=[];let r=0,d=0;const u=t.length-1,c=this.parts,[v,a]=C(t,s);if(this.el=E.createElement(v,n),A.currentNode=this.el.content,2===s){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes)}for(;null!==(l=A.nextNode())&&c.length<u;){if(1===l.nodeType){if(l.hasAttributes()){const t=[];for(const i of l.getAttributeNames())if(i.endsWith("$lit$")||i.startsWith(e)){const s=a[d++];if(t.push(i),void 0!==s){const t=l.getAttribute(s.toLowerCase()+"$lit$").split(e),i=/([.?@])?(.*)/.exec(s);c.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?M:"?"===i[1]?H:"@"===i[1]?I:S})}else c.push({type:6,index:r})}for(const i of t)l.removeAttribute(i)}if(g.test(l.tagName)){const t=l.textContent.split(e),s=t.length-1;if(s>0){l.textContent=i?i.emptyScript:"";for(let i=0;i<s;i++)l.append(t[i],h()),A.nextNode(),c.push({type:2,index:++r});l.append(t[s],h())}}}else if(8===l.nodeType)if(l.data===o)c.push({type:2,index:r});else{let t=-1;for(;-1!==(t=l.data.indexOf(e,t+1));)c.push({type:7,index:r}),t+=e.length-1}r++}}static createElement(t,i){const s=l.createElement("template");return s.innerHTML=t,s}}function P(t,i,s=t,e){var o,n,l,h;if(i===b)return i;let d=void 0!==e?null===(o=s._$Cl)||void 0===o?void 0:o[e]:s._$Cu;const u=r(i)?void 0:i._$litDirective$;return(null==d?void 0:d.constructor)!==u&&(null===(n=null==d?void 0:d._$AO)||void 0===n||n.call(d,!1),void 0===u?d=void 0:(d=new u(t),d._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Cl)&&void 0!==l?l:h._$Cl=[])[e]=d:s._$Cu=d),void 0!==d&&(i=P(t,d._$AS(t,i.values),d,e)),i}class V{constructor(t,i){this.v=[],this._$AN=void 0,this._$AD=t,this._$AM=i}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}p(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:l).importNode(s,!0);A.currentNode=o;let n=A.nextNode(),h=0,r=0,d=e[0];for(;void 0!==d;){if(h===d.index){let i;2===d.type?i=new N(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new L(n,this,t)),this.v.push(i),d=e[++r]}h!==(null==d?void 0:d.index)&&(n=A.nextNode(),h++)}return o}m(t){let i=0;for(const s of this.v)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++}}class N{constructor(t,i,s,e){var o;this.type=2,this._$AH=w,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cg=null===(o=null==e?void 0:e.isConnected)||void 0===o||o}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cg}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=P(this,t,i),r(t)?t===w||null==t||""===t?(this._$AH!==w&&this._$AR(),this._$AH=w):t!==this._$AH&&t!==b&&this.$(t):void 0!==t._$litType$?this.T(t):void 0!==t.nodeType?this.k(t):u(t)?this.S(t):this.$(t)}M(t,i=this._$AB){return this._$AA.parentNode.insertBefore(t,i)}k(t){this._$AH!==t&&(this._$AR(),this._$AH=this.M(t))}$(t){this._$AH!==w&&r(this._$AH)?this._$AA.nextSibling.data=t:this.k(l.createTextNode(t)),this._$AH=t}T(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=E.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.m(s);else{const t=new V(o,this),i=t.p(this.options);t.m(s),this.k(i),this._$AH=t}}_$AC(t){let i=T.get(t.strings);return void 0===i&&T.set(t.strings,i=new E(t)),i}S(t){d(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new N(this.M(h()),this.M(h()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e)}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i}}setConnected(t){var i;void 0===this._$AM&&(this._$Cg=t,null===(i=this._$AP)||void 0===i||i.call(this,t))}}class S{constructor(t,i,s,e,o){this.type=1,this._$AH=w,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=w}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=P(this,t,i,0),n=!r(t)||t!==this._$AH&&t!==b,n&&(this._$AH=t);else{const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=P(this,e[s+l],i,l),h===b&&(h=this._$AH[l]),n||(n=!r(h)||h!==this._$AH[l]),h===w?t=w:t!==w&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h}n&&!e&&this.C(t)}C(t){t===w?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"")}}class M extends S{constructor(){super(...arguments),this.type=3}C(t){this.element[this.name]=t===w?void 0:t}}const k=i?i.emptyScript:"";class H extends S{constructor(){super(...arguments),this.type=4}C(t){t&&t!==w?this.element.setAttribute(this.name,k):this.element.removeAttribute(this.name)}}class I extends S{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5}_$AI(t,i=this){var s;if((t=null!==(s=P(this,t,i,0))&&void 0!==s?s:w)===b)return;const e=this._$AH,o=t===w&&e!==w||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==w&&(e===w||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t)}}class L{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){P(this,t)}}const R={L:"$lit$",P:e,V:o,I:1,N:C,R:V,j:u,D:P,H:N,F:S,O:H,W:I,B:M,Z:L},z=window.litHtmlPolyfillSupport;null==z||z(E,N),(null!==(t=globalThis.litHtmlVersions)&&void 0!==t?t:globalThis.litHtmlVersions=[]).push("2.2.3");export{R as _$LH,$ as html,b as noChange,w as nothing,x as render,y as svg};
+var t;const i=globalThis.trustedTypes,s=i?i.createPolicy("lit-html",{createHTML:t=>t}):void 0,e=`lit$${(Math.random()+"").slice(9)}$`,o="?"+e,n=`<${o}>`,l=document,h=(t="")=>l.createComment(t),r=t=>null===t||"object"!=typeof t&&"function"!=typeof t,d=Array.isArray,u=t=>{var i;return d(t)||"function"==typeof(null===(i=t)||void 0===i?void 0:i[Symbol.iterator])},c=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,a=/>/g,f=/>|[ 	\n\r](?:([^\s"'>=/]+)([ 	\n\r]*=[ 	\n\r]*(?:[^ 	\n\r"'`<>=]|("|')|))|$)/g,_=/'/g,m=/"/g,g=/^(?:script|style|textarea|title)$/i,p=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),$=p(1),y=p(2),b=Symbol.for("lit-noChange"),w=Symbol.for("lit-nothing"),T=new WeakMap,x=(t,i,s)=>{var e,o;const n=null!==(e=null==s?void 0:s.renderBefore)&&void 0!==e?e:i;let l=n._$litPart$;if(void 0===l){const t=null!==(o=null==s?void 0:s.renderBefore)&&void 0!==o?o:null;n._$litPart$=l=new N(i.insertBefore(h(),t),t,void 0,null!=s?s:{})}return l._$AI(t),l},A=l.createTreeWalker(l,129,null,!1),C=(t,i)=>{const o=t.length-1,l=[];let h,r=2===i?"<svg>":"",d=c;for(let i=0;i<o;i++){const s=t[i];let o,u,p=-1,$=0;for(;$<s.length&&(d.lastIndex=$,u=d.exec(s),null!==u);)$=d.lastIndex,d===c?"!--"===u[1]?d=v:void 0!==u[1]?d=a:void 0!==u[2]?(g.test(u[2])&&(h=RegExp("</"+u[2],"g")),d=f):void 0!==u[3]&&(d=f):d===f?">"===u[0]?(d=null!=h?h:c,p=-1):void 0===u[1]?p=-2:(p=d.lastIndex-u[2].length,o=u[1],d=void 0===u[3]?f:'"'===u[3]?m:_):d===m||d===_?d=f:d===v||d===a?d=c:(d=f,h=void 0);const y=d===f&&t[i+1].startsWith("/>")?" ":"";r+=d===c?s+n:p>=0?(l.push(o),s.slice(0,p)+"$lit$"+s.slice(p)+e+y):s+e+(-2===p?(l.push(void 0),i):y)}const u=r+(t[o]||"<?>")+(2===i?"</svg>":"");if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return[void 0!==s?s.createHTML(u):u,l]};class E{constructor({strings:t,_$litType$:s},n){let l;this.parts=[];let r=0,d=0;const u=t.length-1,c=this.parts,[v,a]=C(t,s);if(this.el=E.createElement(v,n),A.currentNode=this.el.content,2===s){const t=this.el.content,i=t.firstChild;i.remove(),t.append(...i.childNodes)}for(;null!==(l=A.nextNode())&&c.length<u;){if(1===l.nodeType){if(l.hasAttributes()){const t=[];for(const i of l.getAttributeNames())if(i.endsWith("$lit$")||i.startsWith(e)){const s=a[d++];if(t.push(i),void 0!==s){const t=l.getAttribute(s.toLowerCase()+"$lit$").split(e),i=/([.?@])?(.*)/.exec(s);c.push({type:1,index:r,name:i[2],strings:t,ctor:"."===i[1]?M:"?"===i[1]?H:"@"===i[1]?I:S})}else c.push({type:6,index:r})}for(const i of t)l.removeAttribute(i)}if(g.test(l.tagName)){const t=l.textContent.split(e),s=t.length-1;if(s>0){l.textContent=i?i.emptyScript:"";for(let i=0;i<s;i++)l.append(t[i],h()),A.nextNode(),c.push({type:2,index:++r});l.append(t[s],h())}}}else if(8===l.nodeType)if(l.data===o)c.push({type:2,index:r});else{let t=-1;for(;-1!==(t=l.data.indexOf(e,t+1));)c.push({type:7,index:r}),t+=e.length-1}r++}}static createElement(t,i){const s=l.createElement("template");return s.innerHTML=t,s}}function P(t,i,s=t,e){var o,n,l,h;if(i===b)return i;let d=void 0!==e?null===(o=s._$Cl)||void 0===o?void 0:o[e]:s._$Cu;const u=r(i)?void 0:i._$litDirective$;return(null==d?void 0:d.constructor)!==u&&(null===(n=null==d?void 0:d._$AO)||void 0===n||n.call(d,!1),void 0===u?d=void 0:(d=new u(t),d._$AT(t,s,e)),void 0!==e?(null!==(l=(h=s)._$Cl)&&void 0!==l?l:h._$Cl=[])[e]=d:s._$Cu=d),void 0!==d&&(i=P(t,d._$AS(t,i.values),d,e)),i}class V{constructor(t,i){this.v=[],this._$AN=void 0,this._$AD=t,this._$AM=i}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}p(t){var i;const{el:{content:s},parts:e}=this._$AD,o=(null!==(i=null==t?void 0:t.creationScope)&&void 0!==i?i:l).importNode(s,!0);A.currentNode=o;let n=A.nextNode(),h=0,r=0,d=e[0];for(;void 0!==d;){if(h===d.index){let i;2===d.type?i=new N(n,n.nextSibling,this,t):1===d.type?i=new d.ctor(n,d.name,d.strings,this,t):6===d.type&&(i=new L(n,this,t)),this.v.push(i),d=e[++r]}h!==(null==d?void 0:d.index)&&(n=A.nextNode(),h++)}return o}m(t){let i=0;for(const s of this.v)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++}}class N{constructor(t,i,s,e){var o;this.type=2,this._$AH=w,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cg=null===(o=null==e?void 0:e.isConnected)||void 0===o||o}get _$AU(){var t,i;return null!==(i=null===(t=this._$AM)||void 0===t?void 0:t._$AU)&&void 0!==i?i:this._$Cg}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=P(this,t,i),r(t)?t===w||null==t||""===t?(this._$AH!==w&&this._$AR(),this._$AH=w):t!==this._$AH&&t!==b&&this.$(t):void 0!==t._$litType$?this.T(t):void 0!==t.nodeType?this.k(t):u(t)?this.S(t):this.$(t)}M(t,i=this._$AB){return this._$AA.parentNode.insertBefore(t,i)}k(t){this._$AH!==t&&(this._$AR(),this._$AH=this.M(t))}$(t){this._$AH!==w&&r(this._$AH)?this._$AA.nextSibling.data=t:this.k(l.createTextNode(t)),this._$AH=t}T(t){var i;const{values:s,_$litType$:e}=t,o="number"==typeof e?this._$AC(t):(void 0===e.el&&(e.el=E.createElement(e.h,this.options)),e);if((null===(i=this._$AH)||void 0===i?void 0:i._$AD)===o)this._$AH.m(s);else{const t=new V(o,this),i=t.p(this.options);t.m(s),this.k(i),this._$AH=t}}_$AC(t){let i=T.get(t.strings);return void 0===i&&T.set(t.strings,i=new E(t)),i}S(t){d(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const o of t)e===i.length?i.push(s=new N(this.M(h()),this.M(h()),this,this.options)):s=i[e],s._$AI(o),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e)}_$AR(t=this._$AA.nextSibling,i){var s;for(null===(s=this._$AP)||void 0===s||s.call(this,!1,!0,i);t&&t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i}}setConnected(t){var i;void 0===this._$AM&&(this._$Cg=t,null===(i=this._$AP)||void 0===i||i.call(this,t))}}class S{constructor(t,i,s,e,o){this.type=1,this._$AH=w,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=w}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,i=this,s,e){const o=this.strings;let n=!1;if(void 0===o)t=P(this,t,i,0),n=!r(t)||t!==this._$AH&&t!==b,n&&(this._$AH=t);else{const e=t;let l,h;for(t=o[0],l=0;l<o.length-1;l++)h=P(this,e[s+l],i,l),h===b&&(h=this._$AH[l]),n||(n=!r(h)||h!==this._$AH[l]),h===w?t=w:t!==w&&(t+=(null!=h?h:"")+o[l+1]),this._$AH[l]=h}n&&!e&&this.C(t)}C(t){t===w?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,null!=t?t:"")}}class M extends S{constructor(){super(...arguments),this.type=3}C(t){this.element[this.name]=t===w?void 0:t}}const k=i?i.emptyScript:"";class H extends S{constructor(){super(...arguments),this.type=4}C(t){t&&t!==w?this.element.setAttribute(this.name,k):this.element.removeAttribute(this.name)}}class I extends S{constructor(t,i,s,e,o){super(t,i,s,e,o),this.type=5}_$AI(t,i=this){var s;if((t=null!==(s=P(this,t,i,0))&&void 0!==s?s:w)===b)return;const e=this._$AH,o=t===w&&e!==w||t.capture!==e.capture||t.once!==e.once||t.passive!==e.passive,n=t!==w&&(e===w||o);o&&this.element.removeEventListener(this.name,this,e),n&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){var i,s;"function"==typeof this._$AH?this._$AH.call(null!==(s=null===(i=this.options)||void 0===i?void 0:i.host)&&void 0!==s?s:this.element,t):this._$AH.handleEvent(t)}}class L{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){P(this,t)}}const R={L:"$lit$",P:e,V:o,I:1,N:C,R:V,j:u,D:P,H:N,F:S,O:H,W:I,B:M,Z:L},z=window.litHtmlPolyfillSupport;null==z||z(E,N),(null!==(t=globalThis.litHtmlVersions)&&void 0!==t?t:globalThis.litHtmlVersions=[]).push("2.2.6");export{R as _$LH,$ as html,b as noChange,w as nothing,x as render,y as svg};
 //# sourceMappingURL=lit-html.js.map
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit-html/package.json b/third_party/material_web_components/components-chromium/node_modules/lit-html/package.json
index c84b29d..53fb04b 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit-html/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/lit-html/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lit-html",
-  "version": "2.2.3",
+  "version": "2.2.6",
   "description": "HTML templates literals in JavaScript",
   "license": "BSD-3-Clause",
   "repository": {
@@ -127,20 +127,17 @@
     }
   },
   "scripts": {
-    "build": "npm run clean && npm run build:ts && npm run build:version-stability-test && rollup -c",
-    "build:watch": "rollup -c --watch",
-    "build:ts": "tsc --build && treemirror development . '**/*.d.ts{,.map}'",
-    "build:ts:watch": "tsc --build --watch",
-    "build:version-stability-test": "rollup -c rollup-version-stability-test.config.js",
-    "check-version": "node scripts/check-version-tracker.js",
-    "checksize": "rollup -c --environment=CHECKSIZE",
-    "clean": "rm -rf {async-directive,directive-helpers,directive,experimental-hydrate,lit-html,polyfill-support,private-ssr-support,static}.{js,js.map,d.ts} test/ directives/ development/ version-stability-test/ *.tsbuildinfo",
-    "dev": "scripts/dev.sh",
+    "build": "wireit",
+    "build:ts": "wireit",
+    "build:ts:types": "wireit",
+    "build:rollup": "wireit",
+    "build:version-stability-test": "wireit",
+    "check-version": "wireit",
+    "checksize": "wireit",
     "prepublishOnly": "npm run check-version",
-    "test": "npm run test:dev && npm run test:prod",
-    "test:dev": "cd ../tests && npx wtr '../lit-html/development/**/*_test.(js|html)'",
-    "test:prod": "MODE=prod npm run test:dev -- '../lit-html/src/test/version-stability_test.js'",
-    "test:watch": "npm run test:dev -- --watch"
+    "test": "wireit",
+    "test:dev": "wireit",
+    "test:prod": "wireit"
   },
   "files": [
     "/async-directive.{d.ts,d.ts.map,js,js.map}",
@@ -155,6 +152,125 @@
     "!/development/test/",
     "/directives/"
   ],
+  "wireit": {
+    "build": {
+      "dependencies": [
+        "build:rollup",
+        "build:ts",
+        "build:ts:types",
+        "build:version-stability-test"
+      ]
+    },
+    "build:ts": {
+      "#comment": "Note this also builds polyfill-support via a TypeScript project reference.",
+      "command": "tsc --build --pretty",
+      "clean": "if-file-deleted",
+      "files": [
+        "src/**/*.ts",
+        "tsconfig.json",
+        "tsconfig.polyfill-support.json"
+      ],
+      "output": [
+        "development",
+        "tsconfig.tsbuildinfo",
+        "tsconfig.polyfill-support.tsbuildinfo"
+      ]
+    },
+    "build:ts:types": {
+      "command": "treemirror development . \"**/*.d.ts{,.map}\"",
+      "dependencies": [
+        "../internal-scripts:build",
+        "build:ts"
+      ],
+      "files": [],
+      "output": [
+        "*.d.ts{,.map}",
+        "directives/*.d.ts{,.map}"
+      ]
+    },
+    "build:rollup": {
+      "command": "rollup -c",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": [
+        "async-directive.js{,.map}",
+        "directive-helpers.js{,.map}",
+        "directive.js{,.map}",
+        "experimental-hydrate.js{,.map}",
+        "lit-html.js{,.map}",
+        "polyfill-support.js{,.map}",
+        "private-ssr-support.js{,.map}",
+        "static.js{,.map}",
+        "directives/*.js{,.map}"
+      ]
+    },
+    "build:version-stability-test": {
+      "command": "rollup -c rollup-version-stability-test.config.js",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup-version-stability-test.config.js",
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": [
+        "version-stability-build"
+      ]
+    },
+    "checksize": {
+      "command": "rollup -c --environment=CHECKSIZE",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": []
+    },
+    "check-version": {
+      "command": "node scripts/check-version-tracker.js",
+      "files": [
+        "scripts/check-version-tracker.js",
+        "package.json",
+        "src/lit-html.ts"
+      ],
+      "output": []
+    },
+    "test": {
+      "dependencies": [
+        "test:dev",
+        "test:prod",
+        "check-version"
+      ]
+    },
+    "test:dev": {
+      "command": "MODE=dev node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    },
+    "test:prod": {
+      "command": "MODE=prod node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:rollup",
+        "build:ts",
+        "build:version-stability-test",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    }
+  },
   "dependencies": {
     "@types/trusted-types": "^2.0.2"
   },
@@ -168,7 +284,7 @@
     "@webcomponents/webcomponentsjs": "^2.6.0",
     "chokidar-cli": "^3.0.0",
     "concurrently": "^6.2.1",
-    "internal-scripts": "^1.0.0",
+    "@lit-internal/scripts": "^1.0.0",
     "mocha": "^9.1.1",
     "rollup": "^2.70.2",
     "typescript": "^4.3.5"
diff --git a/third_party/material_web_components/components-chromium/node_modules/lit/package.json b/third_party/material_web_components/components-chromium/node_modules/lit/package.json
index ada34bf..f543134 100644
--- a/third_party/material_web_components/components-chromium/node_modules/lit/package.json
+++ b/third_party/material_web_components/components-chromium/node_modules/lit/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lit",
-  "version": "2.2.3",
+  "version": "2.2.7",
   "publishConfig": {
     "access": "public"
   },
@@ -136,14 +136,129 @@
     }
   },
   "scripts": {
-    "build": "npm run clean && npm run build:ts && rollup -c",
-    "build:watch": "rollup -c --watch",
-    "build:ts": "tsc --build && treemirror development . '**/*.d.ts{,.map}'",
-    "build:ts:watch": "tsc --build --watch",
-    "clean": "rm -rf {async-directive,decorators,directive-helpers,directive,html,experimental-hydrate-support,experimental-hydrate,index,polyfill-support,static-html}.{d.ts.map,d.ts,js.map,js} test/ decorators/ directives/ development/ *.tsbuildinfo",
-    "publish-dev": "VERSION=${npm_package_version%-*}-dev.`git rev-parse --short HEAD` && npm version --no-git-tag-version $VERSION && npm publish --tag dev",
-    "regen-package-lock": "rm -rf node_modules package-lock.json; npm install",
-    "test": "MODE=prod cd ../tests && npx wtr '../lit/test/**/*_test.(js|html)'"
+    "build": "wireit",
+    "build:ts": "wireit",
+    "build:ts:types": "wireit",
+    "build:rollup": "wireit",
+    "checksize": "wireit",
+    "test": "wireit",
+    "test:dev": "wireit",
+    "test:prod": "wireit"
+  },
+  "wireit": {
+    "build": {
+      "dependencies": [
+        "build:rollup",
+        "build:ts",
+        "build:ts:types",
+        "../lit-html:build",
+        "../lit-element:build",
+        "../reactive-element:build"
+      ]
+    },
+    "build:ts": {
+      "#comment": "Note this also builds polyfill-support via a TypeScript project reference.",
+      "command": "tsc --build --pretty",
+      "clean": "if-file-deleted",
+      "dependencies": [
+        "../lit-element:build:ts:types",
+        "../lit-html:build:ts:types",
+        "../reactive-element:build:ts:types"
+      ],
+      "files": [
+        "src/**/*.ts",
+        "tsconfig.json",
+        "tsconfig.polyfill-support.json"
+      ],
+      "output": [
+        "development/**/*.{js,js.map,d.ts,d.ts.map}",
+        "tsconfig.tsbuildinfo",
+        "tsconfig.polyfill-support.tsbuildinfo"
+      ]
+    },
+    "build:ts:types": {
+      "command": "treemirror development . \"**/*.d.ts{,.map}\"",
+      "dependencies": [
+        "../internal-scripts:build",
+        "build:ts"
+      ],
+      "files": [],
+      "output": [
+        "*.d.ts{,.map}",
+        "decorators/*.d.ts{,.map}",
+        "directives/*.d.ts{,.map}"
+      ]
+    },
+    "build:rollup": {
+      "command": "rollup -c",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js",
+        "src/test/*_test.html",
+        "src/test/polyfill-support/*_test.html"
+      ],
+      "output": [
+        "async-directive.js{,.map}",
+        "decorators.js{,.map}",
+        "directive-helpers.js{,.map}",
+        "directive.js{,.map}",
+        "html.js{,.map}",
+        "experimental-hydrate-support.js{,.map}",
+        "experimental-hydrate.js{,.map}",
+        "index.js{,.map}",
+        "polyfill-support.js{,.map}",
+        "static-html.js{,.map}",
+        "decorators/*.js{,.map}",
+        "directives/*.js{,.map}",
+        "test/*_test.html",
+        "development/test/*_test.html",
+        "test/polyfill-support/*_test.html",
+        "development/test/polyfill-support/*_test.html"
+      ]
+    },
+    "checksize": {
+      "command": "rollup -c --environment=CHECKSIZE",
+      "dependencies": [
+        "build:ts"
+      ],
+      "files": [
+        "rollup.config.js",
+        "../../rollup-common.js"
+      ],
+      "output": []
+    },
+    "test": {
+      "dependencies": [
+        "test:dev",
+        "test:prod"
+      ]
+    },
+    "test:dev": {
+      "#comment": "TODO(aomarks) There is only one lit html test, and it doesn't work",
+      "command": "MODE=dev node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "build:ts",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    },
+    "test:prod": {
+      "command": "MODE=prod node ../tests/run-web-tests.js \"development/**/*_test.(js|html)\" --config ../tests/web-test-runner.config.js",
+      "dependencies": [
+        "../lit-element:build:rollup",
+        "../lit-html:build:rollup",
+        "../reactive-element:build:rollup",
+        "build:ts",
+        "build:rollup",
+        "../tests:build"
+      ],
+      "files": [],
+      "output": []
+    }
   },
   "files": [
     "/async-directive.{d.ts.map,d.ts,js.map,js}",
@@ -174,7 +289,7 @@
     "@webcomponents/webcomponentsjs": "^2.6.0",
     "chokidar-cli": "^3.0.0",
     "downlevel-dts": "^0.7.0",
-    "internal-scripts": "^1.0.0",
+    "@lit-internal/scripts": "^1.0.0",
     "mocha": "^9.1.1",
     "rollup": "^2.70.2",
     "tslib": "^2.0.3",
diff --git a/third_party/material_web_components/package-lock.json b/third_party/material_web_components/package-lock.json
index 651604f1..6b22d13 100644
--- a/third_party/material_web_components/package-lock.json
+++ b/third_party/material_web_components/package-lock.json
@@ -8,7 +8,7 @@
       "name": "chromium-material-web-components",
       "version": "1.0.0",
       "dependencies": {
-        "@material/mwc-button": "0.26.0"
+        "@material/mwc-button": "0.26.1"
       },
       "devDependencies": {
         "acorn": "6.4.2",
@@ -17,115 +17,115 @@
       }
     },
     "node_modules/@lit/reactive-element": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.2.tgz",
-      "integrity": "sha512-A2e18XzPMrIh35nhIdE4uoqRzoIpEU5vZYuQN4S3Ee1zkGdYC27DP12pewbw/RLgPHzaE4kx/YqxMzebOpm0dA=="
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.3.tgz",
+      "integrity": "sha512-ukelZ49tzUqgOAEbVujl/U62JNK3wdn5kKtXVqrjKND4QvHACZOMOYaZI6/5Jd8vsg+Fq9HDwiib70FBLydOiQ=="
     },
     "node_modules/@material/animation": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz",
-      "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-GBuR4VmcTQW1D0lPXEosf5Giho72LLbyGIydWGtaEUtLJoive/D9kFkwTN4Fsyt9Kkl7hbhs35vrNe6QkAH4/Q==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/base": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz",
-      "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-UJKbXwZtkrA3sfQDmj8Zbw1Q3Tqtl6KdfVFws95Yf7TCUgTFzbZI/FSx1w7dVugQPOEnIBuZnzqZam/MtHkx4w==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/dom": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz",
-      "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-aR+rfncF6oi2ivdOlKSJI4UXwNzWV5rXM88MLDoSJF1D7lXxhAKhge+tMUBodWGV/q0+FnXLuVAa0WYTrKjo+A==",
       "dependencies": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/feature-targeting": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz",
-      "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-fn7Af3PRyARtNeYqtjxXmE3Y/dCpnpQVWWys57MqiGR/nvc6qpgOfJ6rOdcu/MrOysOE/oebTUDmDnTmwpe9Hw==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/mwc-base": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.0.tgz",
-      "integrity": "sha512-G2xJQ667OzSieXw3IJzRrjDsngfCOnlVPCkl7TnmCThWziTgQISX6kHOEXPYEXwnJmZZrXcxaoc+aeC5cv+nxQ==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.1.tgz",
+      "integrity": "sha512-YcVvWwSoDwQAxjvYevhZgtyXIIPuMeTnw9MtEj+Hv7NJizT88hoTsPmKpwM+X58cIY2SPo0y/tHfgmblWntibQ==",
       "dependencies": {
-        "@material/base": "=14.0.0",
-        "@material/dom": "=14.0.0",
+        "@material/base": "=14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-button": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.0.tgz",
-      "integrity": "sha512-tRO/uSiajvCSR5YVDSoFC6kPCt2okttYOvAfyVkljgNtnhORekcitgKFNQq6JBN2uvD6s/svJXlW7Xv0j/XCQA==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.1.tgz",
+      "integrity": "sha512-ptgAmg50k+71M6ynfv6QeNaBnX7X/EAnhOjxZqhDHrKwZcFuuQyFJJ6r4ypjc21eCSPS7o6xRqJyI4PPpf3xkA==",
       "dependencies": {
-        "@material/mwc-icon": "^0.26.0",
-        "@material/mwc-ripple": "^0.26.0",
+        "@material/mwc-icon": "^0.26.1",
+        "@material/mwc-ripple": "^0.26.1",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-icon": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.0.tgz",
-      "integrity": "sha512-snI+u1xru4Q9FwEXhVxUoVjY3zvZ+H2ezYZa8Zn3OLArRcuz6R4yDxp1CZelaxTwyK2Sb6Hsp0h3liPCc2zl6A==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.1.tgz",
+      "integrity": "sha512-RPcVPn+5p6hA2HjX/0wkeHQuxkJKgXMg47ffw+vhIw28qM8mprSv13hpUgrghb0f7xBvuPhf/kLb37V4xkRfwg==",
       "dependencies": {
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/mwc-ripple": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.0.tgz",
-      "integrity": "sha512-unDFbwhZiqojOLF20/5MnYghBk1V1H1r7mJbXG7Jam8x/V1nbdljPIXj0EP3YInt5dBPQHKcf+JkW1En1LGNFw==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.1.tgz",
+      "integrity": "sha512-hBeC2S7TSYLmHetXbtu52/EZFzvAqrQk5skIV0aUZeZvywTJWRVoc5OavDjsJYuKxDnSECMnkIt8+l8WC48chg==",
       "dependencies": {
-        "@material/dom": "=14.0.0",
-        "@material/mwc-base": "^0.26.0",
-        "@material/ripple": "=14.0.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
+        "@material/mwc-base": "^0.26.1",
+        "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "node_modules/@material/ripple": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz",
-      "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-6g2G62vd8DsMuIUSXlRrzb98qkZ4o8ZREknNwNP2zaLQEOkJ//4j9HaqDt98/3LIjUTY9UIVFTQENiMmlwKHYQ==",
       "dependencies": {
-        "@material/animation": "^14.0.0",
-        "@material/base": "^14.0.0",
-        "@material/dom": "^14.0.0",
-        "@material/feature-targeting": "^14.0.0",
-        "@material/rtl": "^14.0.0",
-        "@material/theme": "^14.0.0",
+        "@material/animation": "14.0.0-canary.53b3cad2f.0",
+        "@material/base": "14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "14.0.0-canary.53b3cad2f.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
+        "@material/rtl": "14.0.0-canary.53b3cad2f.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/rtl": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz",
-      "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-f08LT0HSa0WYU+4Jz/tbm1TQ9Fcf2k+H6dPPYv0J1sZmX6hMgCEmNiUdUFLQFvszoXx2XrRi1/hIFjbz2e69Yg==",
       "dependencies": {
-        "@material/theme": "^14.0.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "node_modules/@material/theme": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz",
-      "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-S06XAevDCDWMe+GgsEpITMS07imUidzadNaTbJsqssFajBLr53QWVZsG84BpjXKXoYvyEJvb0hX5U0lq6ip9UQ==",
       "dependencies": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
@@ -184,9 +184,9 @@
       }
     },
     "node_modules/lit": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.3.tgz",
-      "integrity": "sha512-5/v+r9dH3Pw/o0rhp/qYk3ERvOUclNF31bWb0FiW6MPgwdQIr+/KCt/p3zcd8aPl8lIGnxdGrVcZA+gWS6oFOQ==",
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.7.tgz",
+      "integrity": "sha512-WXYujlKFwme5ZqXOZoWuRVZQAwy7scbcVT3wCbAOHefOxyscqjywWGlF2e6nnC9E64yP9l2ZQlN8wZcRlrjUMQ==",
       "dependencies": {
         "@lit/reactive-element": "^1.3.0",
         "lit-element": "^3.2.0",
@@ -194,18 +194,18 @@
       }
     },
     "node_modules/lit-element": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
-      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.1.tgz",
+      "integrity": "sha512-2PxyE9Yq9Jyo/YBK2anycaHcqo93YvB5D+24JxloPVqryW/BOXekne+jGsm0Ke3E5E2v7CDgkmpEmCAzYfrHCQ==",
       "dependencies": {
         "@lit/reactive-element": "^1.3.0",
         "lit-html": "^2.2.0"
       }
     },
     "node_modules/lit-html": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.3.tgz",
-      "integrity": "sha512-vI4j3eWwtQaR8q/O63juZVliBIFMio716X719/lSsGH4UWPy2/7Qf377jsNs4cx3gCHgIbx8yxFgXFQ/igZyXQ==",
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.6.tgz",
+      "integrity": "sha512-xOKsPmq/RAKJ6dUeOxhmOYFjcjf0Q7aSdfBJgdJkOfCUnkmmJPxNrlZpRBeVe1Gg50oYWMlgm6ccAE/SpJgSdw==",
       "dependencies": {
         "@types/trusted-types": "^2.0.2"
       }
@@ -254,115 +254,115 @@
   },
   "dependencies": {
     "@lit/reactive-element": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.2.tgz",
-      "integrity": "sha512-A2e18XzPMrIh35nhIdE4uoqRzoIpEU5vZYuQN4S3Ee1zkGdYC27DP12pewbw/RLgPHzaE4kx/YqxMzebOpm0dA=="
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.3.tgz",
+      "integrity": "sha512-ukelZ49tzUqgOAEbVujl/U62JNK3wdn5kKtXVqrjKND4QvHACZOMOYaZI6/5Jd8vsg+Fq9HDwiib70FBLydOiQ=="
     },
     "@material/animation": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz",
-      "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-GBuR4VmcTQW1D0lPXEosf5Giho72LLbyGIydWGtaEUtLJoive/D9kFkwTN4Fsyt9Kkl7hbhs35vrNe6QkAH4/Q==",
       "requires": {
         "tslib": "^2.1.0"
       }
     },
     "@material/base": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz",
-      "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-UJKbXwZtkrA3sfQDmj8Zbw1Q3Tqtl6KdfVFws95Yf7TCUgTFzbZI/FSx1w7dVugQPOEnIBuZnzqZam/MtHkx4w==",
       "requires": {
         "tslib": "^2.1.0"
       }
     },
     "@material/dom": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz",
-      "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-aR+rfncF6oi2ivdOlKSJI4UXwNzWV5rXM88MLDoSJF1D7lXxhAKhge+tMUBodWGV/q0+FnXLuVAa0WYTrKjo+A==",
       "requires": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "@material/feature-targeting": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz",
-      "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-fn7Af3PRyARtNeYqtjxXmE3Y/dCpnpQVWWys57MqiGR/nvc6qpgOfJ6rOdcu/MrOysOE/oebTUDmDnTmwpe9Hw==",
       "requires": {
         "tslib": "^2.1.0"
       }
     },
     "@material/mwc-base": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.0.tgz",
-      "integrity": "sha512-G2xJQ667OzSieXw3IJzRrjDsngfCOnlVPCkl7TnmCThWziTgQISX6kHOEXPYEXwnJmZZrXcxaoc+aeC5cv+nxQ==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-base/-/mwc-base-0.26.1.tgz",
+      "integrity": "sha512-YcVvWwSoDwQAxjvYevhZgtyXIIPuMeTnw9MtEj+Hv7NJizT88hoTsPmKpwM+X58cIY2SPo0y/tHfgmblWntibQ==",
       "requires": {
-        "@material/base": "=14.0.0",
-        "@material/dom": "=14.0.0",
+        "@material/base": "=14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "@material/mwc-button": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.0.tgz",
-      "integrity": "sha512-tRO/uSiajvCSR5YVDSoFC6kPCt2okttYOvAfyVkljgNtnhORekcitgKFNQq6JBN2uvD6s/svJXlW7Xv0j/XCQA==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-button/-/mwc-button-0.26.1.tgz",
+      "integrity": "sha512-ptgAmg50k+71M6ynfv6QeNaBnX7X/EAnhOjxZqhDHrKwZcFuuQyFJJ6r4ypjc21eCSPS7o6xRqJyI4PPpf3xkA==",
       "requires": {
-        "@material/mwc-icon": "^0.26.0",
-        "@material/mwc-ripple": "^0.26.0",
+        "@material/mwc-icon": "^0.26.1",
+        "@material/mwc-ripple": "^0.26.1",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "@material/mwc-icon": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.0.tgz",
-      "integrity": "sha512-snI+u1xru4Q9FwEXhVxUoVjY3zvZ+H2ezYZa8Zn3OLArRcuz6R4yDxp1CZelaxTwyK2Sb6Hsp0h3liPCc2zl6A==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.26.1.tgz",
+      "integrity": "sha512-RPcVPn+5p6hA2HjX/0wkeHQuxkJKgXMg47ffw+vhIw28qM8mprSv13hpUgrghb0f7xBvuPhf/kLb37V4xkRfwg==",
       "requires": {
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "@material/mwc-ripple": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.0.tgz",
-      "integrity": "sha512-unDFbwhZiqojOLF20/5MnYghBk1V1H1r7mJbXG7Jam8x/V1nbdljPIXj0EP3YInt5dBPQHKcf+JkW1En1LGNFw==",
+      "version": "0.26.1",
+      "resolved": "https://registry.npmjs.org/@material/mwc-ripple/-/mwc-ripple-0.26.1.tgz",
+      "integrity": "sha512-hBeC2S7TSYLmHetXbtu52/EZFzvAqrQk5skIV0aUZeZvywTJWRVoc5OavDjsJYuKxDnSECMnkIt8+l8WC48chg==",
       "requires": {
-        "@material/dom": "=14.0.0",
-        "@material/mwc-base": "^0.26.0",
-        "@material/ripple": "=14.0.0",
+        "@material/dom": "=14.0.0-canary.53b3cad2f.0",
+        "@material/mwc-base": "^0.26.1",
+        "@material/ripple": "=14.0.0-canary.53b3cad2f.0",
         "lit": "^2.0.0",
         "tslib": "^2.0.1"
       }
     },
     "@material/ripple": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz",
-      "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-6g2G62vd8DsMuIUSXlRrzb98qkZ4o8ZREknNwNP2zaLQEOkJ//4j9HaqDt98/3LIjUTY9UIVFTQENiMmlwKHYQ==",
       "requires": {
-        "@material/animation": "^14.0.0",
-        "@material/base": "^14.0.0",
-        "@material/dom": "^14.0.0",
-        "@material/feature-targeting": "^14.0.0",
-        "@material/rtl": "^14.0.0",
-        "@material/theme": "^14.0.0",
+        "@material/animation": "14.0.0-canary.53b3cad2f.0",
+        "@material/base": "14.0.0-canary.53b3cad2f.0",
+        "@material/dom": "14.0.0-canary.53b3cad2f.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
+        "@material/rtl": "14.0.0-canary.53b3cad2f.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "@material/rtl": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz",
-      "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-f08LT0HSa0WYU+4Jz/tbm1TQ9Fcf2k+H6dPPYv0J1sZmX6hMgCEmNiUdUFLQFvszoXx2XrRi1/hIFjbz2e69Yg==",
       "requires": {
-        "@material/theme": "^14.0.0",
+        "@material/theme": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
     "@material/theme": {
-      "version": "14.0.0",
-      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz",
-      "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==",
+      "version": "14.0.0-canary.53b3cad2f.0",
+      "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0-canary.53b3cad2f.0.tgz",
+      "integrity": "sha512-S06XAevDCDWMe+GgsEpITMS07imUidzadNaTbJsqssFajBLr53QWVZsG84BpjXKXoYvyEJvb0hX5U0lq6ip9UQ==",
       "requires": {
-        "@material/feature-targeting": "^14.0.0",
+        "@material/feature-targeting": "14.0.0-canary.53b3cad2f.0",
         "tslib": "^2.1.0"
       }
     },
@@ -408,9 +408,9 @@
       }
     },
     "lit": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.3.tgz",
-      "integrity": "sha512-5/v+r9dH3Pw/o0rhp/qYk3ERvOUclNF31bWb0FiW6MPgwdQIr+/KCt/p3zcd8aPl8lIGnxdGrVcZA+gWS6oFOQ==",
+      "version": "2.2.7",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.7.tgz",
+      "integrity": "sha512-WXYujlKFwme5ZqXOZoWuRVZQAwy7scbcVT3wCbAOHefOxyscqjywWGlF2e6nnC9E64yP9l2ZQlN8wZcRlrjUMQ==",
       "requires": {
         "@lit/reactive-element": "^1.3.0",
         "lit-element": "^3.2.0",
@@ -418,18 +418,18 @@
       }
     },
     "lit-element": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
-      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.1.tgz",
+      "integrity": "sha512-2PxyE9Yq9Jyo/YBK2anycaHcqo93YvB5D+24JxloPVqryW/BOXekne+jGsm0Ke3E5E2v7CDgkmpEmCAzYfrHCQ==",
       "requires": {
         "@lit/reactive-element": "^1.3.0",
         "lit-html": "^2.2.0"
       }
     },
     "lit-html": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.3.tgz",
-      "integrity": "sha512-vI4j3eWwtQaR8q/O63juZVliBIFMio716X719/lSsGH4UWPy2/7Qf377jsNs4cx3gCHgIbx8yxFgXFQ/igZyXQ==",
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.6.tgz",
+      "integrity": "sha512-xOKsPmq/RAKJ6dUeOxhmOYFjcjf0Q7aSdfBJgdJkOfCUnkmmJPxNrlZpRBeVe1Gg50oYWMlgm6ccAE/SpJgSdw==",
       "requires": {
         "@types/trusted-types": "^2.0.2"
       }
diff --git a/third_party/material_web_components/package.json b/third_party/material_web_components/package.json
index 967f7c4..3dbe3db 100644
--- a/third_party/material_web_components/package.json
+++ b/third_party/material_web_components/package.json
@@ -3,7 +3,7 @@
   "version": "1.0.0",
   "author": "calamity@chromium.org",
   "dependencies": {
-    "@material/mwc-button": "0.26.0"
+    "@material/mwc-button": "0.26.1"
   },
   "devDependencies": {
     "acorn": "6.4.2",
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index fefcf3f5..577dc63 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -946,7 +946,7 @@
       'android-cronet-x86-rel-kitkat-tests': 'android_cronet_release_bot_minimal_symbols_x86',
       'android-deterministic-dbg': 'android_debug_bot',
       'android-deterministic-rel': 'android_without_codecs_release_trybot',
-      'android-fieldtrial-fyi-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_monochrome_reclient',
+      'android-fieldtrial-rel': 'android_release_trybot',
       'android-inverse-fieldtrials-pie-x86-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google_invert_fieldtrials',
       'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_fastbuild_java_coverage',
       'android-marshmallow-x86-fyi-rel-reviver': 'android_release_trybot_x86_fastbuild_webview_google',
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index bc52d381..7867824 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -518,21 +518,17 @@
       "use_goma": true
     }
   },
-  "android-fieldtrial-fyi-rel": {
+  "android-fieldtrial-rel": {
     "gn_args": {
-      "dcheck_always_on": false,
-      "disable_android_lint": true,
+      "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
       "strip_debug_info": true,
-      "symbol_level": 1,
-      "system_webview_package_name": "com.google.android.apps.chrome",
-      "target_cpu": "x86",
+      "symbol_level": 0,
       "target_os": "android",
-      "use_errorprone_java_compiler": false,
-      "use_remoteexec": true
+      "use_goma": true
     }
   },
   "android-inverse-fieldtrials-pie-x86-fyi-rel": {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index b653959..bfc5e8f 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -3715,6 +3715,46 @@
   </description>
 </action>
 
+<action name="Ash_ClipboardHistory_PastedItem1">
+  <owner>ckincaid@chromium.org</owner>
+  <owner>multipaste@google.com</owner>
+  <description>
+    Emitted when a user pastes the first item from their clipboard history.
+  </description>
+</action>
+
+<action name="Ash_ClipboardHistory_PastedItem2">
+  <owner>ckincaid@chromium.org</owner>
+  <owner>multipaste@google.com</owner>
+  <description>
+    Emitted when a user pastes the second item from their clipboard history.
+  </description>
+</action>
+
+<action name="Ash_ClipboardHistory_PastedItem3">
+  <owner>ckincaid@chromium.org</owner>
+  <owner>multipaste@google.com</owner>
+  <description>
+    Emitted when a user pastes the third item from their clipboard history.
+  </description>
+</action>
+
+<action name="Ash_ClipboardHistory_PastedItem4">
+  <owner>ckincaid@chromium.org</owner>
+  <owner>multipaste@google.com</owner>
+  <description>
+    Emitted when a user pastes the fourth item from their clipboard history.
+  </description>
+</action>
+
+<action name="Ash_ClipboardHistory_PastedItem5">
+  <owner>ckincaid@chromium.org</owner>
+  <owner>multipaste@google.com</owner>
+  <description>
+    Emitted when a user pastes the fifth item from their clipboard history.
+  </description>
+</action>
+
 <action name="Ash_Tablet_BackGesture">
   <owner>minch@chromium.org</owner>
   <owner>tclaiborne@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index e70820a..f428a33 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -35022,6 +35022,7 @@
   <int value="1680" label="PASSWORDSPRIVATE_STARTAUTOMATEDPASSWORDCHANGE"/>
   <int value="1681" label="OFFSCREEN_CREATEDOCUMENT"/>
   <int value="1682" label="PASSWORDSPRIVATE_REFRESHSCRIPTSIFNECESSARY"/>
+  <int value="1683" label="OFFSCREEN_CLOSEDOCUMENT"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -41077,6 +41078,12 @@
              X button to close the notice."/>
 </enum>
 
+<enum name="FeedPositionSegmentationResult">
+  <int value="0" label="Uninitialized."/>
+  <int value="1" label="Is a Feed active user."/>
+  <int value="2" label="Is a non-Feed user."/>
+</enum>
+
 <enum name="FeedRequestReason">
   <int value="0" label="UNKNOWN"/>
   <int value="1" label="ZERO_STATE"/>
@@ -85332,7 +85339,22 @@
   <int value="8" label="Throttle prevented the prefetch"/>
 </enum>
 
-<enum name="SearchPrefetchFinalStatus">
+<enum name="SearchPrefetchServingReason">
+  <int value="0" label="Served a prefetch response"/>
+  <int value="1" label="Search engine not set"/>
+  <int value="2" label="User disabled Javascript"/>
+  <int value="3" label="Navigation URL was not a default search URL"/>
+  <int value="4" label="No prefetch issued for the search terms"/>
+  <int value="5" label="Prefetch was for a different origin"/>
+  <int value="6" label="Prefetch request was cancelled"/>
+  <int value="7" label="Prefetch request failed"/>
+  <int value="8" label="Another reason (unexpected)"/>
+  <int value="9" label="POST, reload, link, or other non-cache loads."/>
+  <int value="10"
+      label="A prerender navigation request has taken this response away."/>
+</enum>
+
+<enum name="SearchPrefetchStatus">
   <int value="0" label="Not started"/>
   <int value="1" label="In flight"/>
   <int value="2" label="Headers received (for streaming responses)"/>
@@ -85350,21 +85372,6 @@
   <int value="10" label="Upgraded to prerender and succeeded"/>
 </enum>
 
-<enum name="SearchPrefetchServingReason">
-  <int value="0" label="Served a prefetch response"/>
-  <int value="1" label="Search engine not set"/>
-  <int value="2" label="User disabled Javascript"/>
-  <int value="3" label="Navigation URL was not a default search URL"/>
-  <int value="4" label="No prefetch issued for the search terms"/>
-  <int value="5" label="Prefetch was for a different origin"/>
-  <int value="6" label="Prefetch request was cancelled"/>
-  <int value="7" label="Prefetch request failed"/>
-  <int value="8" label="Another reason (unexpected)"/>
-  <int value="9" label="POST, reload, link, or other non-cache loads."/>
-  <int value="10"
-      label="A prerender navigation request has taken this response away."/>
-</enum>
-
 <enum name="SearchResultExtractorClientStatus">
   <int value="0" label="Success"/>
   <int value="1" label="No results"/>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
index 7756686..3cad52e9 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -855,6 +855,18 @@
   </summary>
 </histogram>
 
+<histogram name="NewTabPage.FeedPositionSegmentationResult"
+    enum="FeedPositionSegmentationResult" expires_after="2022-09-24">
+  <owner>hanxi@chromium.org</owner>
+  <owner>ssid@chromium.org</owner>
+  <owner>spdonghao@chromium.org</owner>
+  <summary>
+    Logs the result from segmentation platform that determines whether the user
+    is a Feed active user or a non-Feed user. Recorded three times when a new
+    tab page is shown and Feed position (target) experiment is enabled.
+  </summary>
+</histogram>
+
 <histogram name="NewTabPage.HasCredentials" enum="BooleanYesNo"
     expires_after="2022-11-20">
   <owner>danpeng@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml
index 636cc3d..59899c8 100644
--- a/tools/metrics/histograms/metadata/omnibox/histograms.xml
+++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -22,6 +22,31 @@
 
 <histograms>
 
+<variants name="OmniboxProviders">
+  <variant name="Bookmark"/>
+  <variant name="Builtin"/>
+  <variant name="Clipboard"/>
+  <variant name="Contact"/>
+  <variant name="Document"/>
+  <variant name="ExtensionApp"/>
+  <variant name="HistoryCluster"/>
+  <variant name="HistoryContents"/>
+  <variant name="HistoryFuzzy"/>
+  <variant name="HistoryQuick"/>
+  <variant name="HistoryURL"/>
+  <variant name="Keyword"/>
+  <variant name="LocalHistoryZeroSuggest"/>
+  <variant name="MostVisitedSites"/>
+  <variant name="OnDeviceHead"/>
+  <variant name="OpenTab"/>
+  <variant name="QueryTile"/>
+  <variant name="Search"/>
+  <variant name="Shortcuts"/>
+  <variant name="VerbatimMatch"/>
+  <variant name="VoiceSuggest"/>
+  <variant name="ZeroSuggest"/>
+</variants>
+
 <histogram name="Omnibox.AcceptedKeywordSuggestion"
     enum="OmniboxEnteredKeywordMode2" expires_after="2022-11-10">
   <owner>yoangela@chromium.org</owner>
@@ -74,6 +99,152 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Omnibox.AsyncAutocompletionTime.Provider.{Provider}{Completed}"
+    units="ms" expires_after="2022-12-01">
+  <owner>manukh@chromium.org</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>chrome-omnibox-team@google.com</owner>
+  <summary>
+    When the user focuses or types into the omnibox, the dropdown results can be
+    updated multiple times per input (i.e. when focused, per char typed,
+    backspace, etc).
+
+    Specifically, the set of events that trigger dropdown updates are:
+
+    - synchronous suggestions
+
+    - asynchronous suggestions. Can trigger multiple times per input. These are
+    often generated on different threads.
+
+    - expiring copied matches
+
+    - interruptions e.g. additional user input changes or closing the dropdown
+
+    A sample flow looks like:
+
+    1) User types a character.
+
+    2) 10ms later, update results with synchronous suggestions.
+
+    3) 50ms later, update results with some asynchronous suggestions.
+
+    4) 50ms later, update results with more asynchronous suggestions.
+
+    5) 400ms later, update results by removing copied matches from the previous
+    input.
+
+    6) 50 later, update results with the last batch of asynchronous suggestions.
+
+    The 'Provider.*' slices measure the time between the input change and the
+    last async update of that provider is done or interrupted. Includes async
+    updates that have no user visible change (i.e. that do not produce async
+    matches or produce only async matches that get deduped, culled, or are the
+    same as the existing match in its position). Only logged for asynchronous
+    providers. Emitted exactly once per input per asynchronous provider;
+    additionally emits to exactly one of the 'Completed' and 'Interrupted'
+    slices per input per asynchronous provider.
+
+    {Completed}
+  </summary>
+  <token key="Provider" variants="OmniboxProviders"/>
+  <token key="Completed">
+    <variant name=""/>
+    <variant name=".Completed"
+        summary="The 'Completed' slice only includes inputs that completed;
+                 i.e. the last async update completed without interruption
+                 by, e.g., closing the omnibox dropdown."/>
+    <variant name=".Interrupted"
+        summary="The 'Interrupted' slice only includes inputs that were
+                 interrupted; i.e. the last async update was interrupted by,
+                 e.g., closing the omnibox dropdown before completing. It can
+                 be misleading to interpret this slice, as neither an
+                 increase or decrease is necessarily good."/>
+  </token>
+</histogram>
+
+<histogram name="Omnibox.AsyncAutocompletionTime.{Change}{Completed}"
+    units="ms" expires_after="2022-12-01">
+  <owner>manukh@chromium.org</owner>
+  <owner>jdonnelly@chromium.org</owner>
+  <owner>chrome-omnibox-team@google.com</owner>
+  <summary>
+    When the user focuses or types into the omnibox, the dropdown results can be
+    updated multiple times per input (i.e. when focused, per char typed,
+    backspace, etc).
+
+    Specifically, the set of events that trigger dropdown updates are:
+
+    - synchronous suggestions
+
+    - asynchronous suggestions. Can trigger multiple times per input. These are
+    often generated on different threads.
+
+    - expiring copied matches
+
+    - interruptions e.g. additional user input changes or closing the dropdown
+
+    A sample flow looks like:
+
+    1) User types a character.
+
+    2) 10ms later, update results with synchronous suggestions.
+
+    3) 50ms later, update results with some asynchronous suggestions.
+
+    4) 50ms later, update results with more asynchronous suggestions.
+
+    5) 400ms later, update results by removing copied matches from the previous
+    input.
+
+    6) 50 later, update results with the last batch of asynchronous suggestions.
+
+    {Change}
+
+    {Completed}
+  </summary>
+  <token key="Change">
+    <variant name="Done"
+        summary="The 'Done' slice measures the time between input change and
+                 the last async update is done or interrupted. Includes async
+                 updates that have no user visible change (i.e. that do not
+                 produce async matches or produce only async matches that get
+                 deduped, culled, or are the same as the existing match in
+                 its position). Emitted exactly once per input; additionally
+                 emits to exactly one of the 'Completed' and 'Interrupted'
+                 slices per input."/>
+    <variant name="LastChange"
+        summary="The 'LastChange' slice measures the time between input
+                 change and the last async update that made at least 1 change
+                 to the results. Updates that produce only async matches that
+                 get deduped, culled, or are the same as the existing match
+                 in its position are not included. Emitted exactly once per
+                 input; additionally emits to exactly one of the 'Completed'
+                 and 'Interrupted' slices per input."/>
+    <variant name="LastDefaultChange"
+        summary="The 'LastDefaultChange' slice measures the time between
+                 input change and the last async update that changed the
+                 default suggestion. Updates that produce an async default
+                 match that is the same as the existing default match are not
+                 included. Emitted exactly once per input; additionally emits
+                 to exactly one of the 'Completed' and 'Interrupted' slices
+                 per input."/>
+  </token>
+  <token key="Completed">
+    <variant name=""/>
+    <variant name=".Completed"
+        summary="The 'Completed' slice only includes inputs that completed;
+                 i.e. the last async update completed without interruption
+                 by, e.g., closing the omnibox dropdown."/>
+    <variant name=".Interrupted"
+        summary="The 'Interrupted' slice only includes inputs that were
+                 interrupted; i.e. the last async update was interrupted by,
+                 e.g., closing the omnibox dropdown before completing. It can
+                 be misleading to interpret this slice, as neither an
+                 increase or decrease is necessarily good."/>
+  </token>
+</histogram>
+
 <histogram name="Omnibox.BitmapFetchLatency" units="ms"
     expires_after="2022-09-11">
   <obsolete>
@@ -872,30 +1043,7 @@
     The length of time taken by the {OmniboxProvider}Provider's synchronous
     pass.
   </summary>
-  <token key="OmniboxProvider">
-    <variant name="Bookmark"/>
-    <variant name="Builtin"/>
-    <variant name="Clipboard"/>
-    <variant name="Contact"/>
-    <variant name="Document"/>
-    <variant name="ExtensionApp"/>
-    <variant name="HistoryCluster"/>
-    <variant name="HistoryContents"/>
-    <variant name="HistoryFuzzy"/>
-    <variant name="HistoryQuick"/>
-    <variant name="HistoryURL"/>
-    <variant name="Keyword"/>
-    <variant name="LocalHistoryZeroSuggest"/>
-    <variant name="MostVisitedSites"/>
-    <variant name="OnDeviceHead"/>
-    <variant name="OpenTab"/>
-    <variant name="QueryTile"/>
-    <variant name="Search"/>
-    <variant name="Shortcuts"/>
-    <variant name="VerbatimMatch"/>
-    <variant name="VoiceSuggest"/>
-    <variant name="ZeroSuggest"/>
-  </token>
+  <token key="OmniboxProvider" variants="OmniboxProviders"/>
 </histogram>
 
 <histogram name="Omnibox.QueryTime2" units="ms" expires_after="2022-11-13">
@@ -1210,7 +1358,7 @@
 </histogram>
 
 <histogram name="Omnibox.SearchPrefetch.PrefetchFinalStatus.NavigationPrefetch"
-    enum="SearchPrefetchFinalStatus" expires_after="2022-10-30">
+    enum="SearchPrefetchStatus" expires_after="2022-10-30">
   <owner>ryansturm@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
   <summary>
@@ -1234,7 +1382,7 @@
 </histogram>
 
 <histogram name="Omnibox.SearchPrefetch.PrefetchFinalStatus.SuggestionPrefetch"
-    enum="SearchPrefetchFinalStatus" expires_after="2022-08-07">
+    enum="SearchPrefetchStatus" expires_after="2022-08-07">
   <owner>ryansturm@chromium.org</owner>
   <owner>chrome-omnibox-team@google.com</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index fae3c5f..0761af3 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,16 +5,16 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "6a60287982c53d9a6f658dba9b30925fc64e9108",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/a9181a27b59a2e431c946d91cfcd33b7ae6a2b80/trace_processor_shell.exe"
+            "hash": "69c1ac1a94c9a17f492086a1962cf1630db27f2e",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/f56e4abd18a85f6719dcff6fcdc305673d0f3f4e/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "b703de4b0c4254a2f20eca3d6226af3f7de8ba00",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/3c4bdd0f331990d7fae52ae52f56f5762614cc33/trace_processor_shell"
+            "hash": "0d726a5fad386a2bd9a3d68b92ccbba0e1065ad6",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/f56e4abd18a85f6719dcff6fcdc305673d0f3f4e/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
diff --git a/tools/polymer/css_to_wrapper.gni b/tools/polymer/css_to_wrapper.gni
index 3b305ee..1542a9d 100644
--- a/tools/polymer/css_to_wrapper.gni
+++ b/tools/polymer/css_to_wrapper.gni
@@ -44,5 +44,9 @@
              rebase_path(out_folder, root_build_dir),
              "--in_files",
            ] + invoker.in_files
+
+    if (defined(invoker.minify) && invoker.minify) {
+      args += [ "--minify" ]
+    }
   }
 }
diff --git a/tools/polymer/css_to_wrapper.py b/tools/polymer/css_to_wrapper.py
index 5830c19..2a96921 100644
--- a/tools/polymer/css_to_wrapper.py
+++ b/tools/polymer/css_to_wrapper.py
@@ -9,13 +9,20 @@
 # example foo_style.css will be held in a module with ID 'foo-style'.
 
 import argparse
-import sys
 import io
 import re
+import shutil
+import sys
+import tempfile
 from os import path, getcwd, makedirs
 
+_HERE_PATH = path.dirname(__file__)
+_SRC_PATH = path.normpath(path.join(_HERE_PATH, '..', '..'))
 _CWD = getcwd()
 
+sys.path.append(path.join(_SRC_PATH, 'third_party', 'node'))
+import node
+
 _METADATA_START_REGEX = '#css_wrapper_metadata_start'
 _METADATA_END_REGEX = '#css_wrapper_metadata_end'
 _IMPORT_REGEX = '#import='
@@ -49,28 +56,40 @@
 document.head.appendChild($_documentContainer.content);"""
 
 
-def _parse_style_line(line, parsed_data):
-  if not parsed_data['include']:
+def _parse_style_line(line, metadata):
+  if not metadata['include']:
     include_match = re.search(_INCLUDE_REGEX, line)
     if include_match:
-      parsed_data['include'] = line[include_match.end():]
+      metadata['include'] = line[include_match.end():]
 
   import_match = re.search(_IMPORT_REGEX, line)
   if import_match:
-    parsed_data['imports'].append(line[import_match.end():])
+    metadata['imports'].append(line[import_match.end():])
 
 
-def _parse_vars_line(line, parsed_data):
+def _parse_vars_line(line, metadata):
   import_match = re.search(_IMPORT_REGEX, line)
   if import_match:
-    parsed_data['imports'].append(line[import_match.end():])
+    metadata['imports'].append(line[import_match.end():])
 
 
-def _extract_data(css_file):
+def _extract_content(css_file, metadata, minified):
+  with io.open(css_file, encoding='utf-8', mode='r') as f:
+    # If minification is on, just grab the result from html-minifier's output.
+    if minified:
+      return f.read()
+
+    # If minification is off, strip the special metadata comments from the
+    # original file.
+    lines = f.read().splitlines()
+    return '\n'.join(lines[metadata['metadata_end_line'] + 1:])
+
+
+def _extract_metadata(css_file):
   metadata_start_line = -1
   metadata_end_line = -1
 
-  parsed_data = {'type': None}
+  metadata = {'type': None}
 
   with io.open(css_file, encoding='utf-8', mode='r') as f:
     lines = f.read().splitlines()
@@ -83,7 +102,7 @@
       else:
         assert metadata_end_line == -1
 
-        if not parsed_data['type']:
+        if not metadata['type']:
           type_match = re.search(_TYPE_REGEX, line)
           if type_match:
             type = line[type_match.end():]
@@ -91,36 +110,35 @@
 
             if type == 'style':
               id = path.splitext(path.basename(css_file))[0].replace('_', '-')
-              parsed_data = {
-                  'content': None,
+              metadata = {
                   'id': id,
                   'imports': [],
                   'include': None,
+                  'metadata_end_line': -1,
                   'type': type,
               }
             elif type == 'vars':
-              parsed_data = {
-                  'content': None,
+              metadata = {
                   'imports': [],
+                  'metadata_end_line': -1,
                   'type': type,
               }
 
-        elif parsed_data['type'] == 'style':
-          _parse_style_line(line, parsed_data)
-        elif parsed_data['type'] == 'vars':
-          _parse_vars_line(line, parsed_data)
+        elif metadata['type'] == 'style':
+          _parse_style_line(line, metadata)
+        elif metadata['type'] == 'vars':
+          _parse_vars_line(line, metadata)
 
         if _METADATA_END_REGEX in line:
           assert metadata_start_line > -1
           metadata_end_line = i
-          parsed_data['content'] = '\n'.join(lines[metadata_end_line + 1:])
+          metadata['metadata_end_line'] = metadata_end_line
           break
 
     assert metadata_start_line > -1
     assert metadata_end_line > -1
-    assert parsed_data['content']
 
-    return parsed_data
+    return metadata
 
 
 def main(argv):
@@ -128,35 +146,69 @@
   parser.add_argument('--in_folder', required=True)
   parser.add_argument('--out_folder', required=True)
   parser.add_argument('--in_files', required=True, nargs="*")
+  parser.add_argument('--minify', action='store_true')
   args = parser.parse_args(argv)
 
   in_folder = path.normpath(path.join(_CWD, args.in_folder))
   out_folder = path.normpath(path.join(_CWD, args.out_folder))
   extension = '.ts'
 
+  # The folder to be used to read the CSS files to be wrapped.
+  wrapper_in_folder = in_folder
+
+  if args.minify:
+    # Minify the CSS files with html-minifier before generating the wrapper
+    # .ts files.
+    # Note: Passing all CSS files to html-minifier all at once because
+    # passing them individually takes a lot longer.
+    # Storing the output in a temporary folder, which is used further below when
+    # creating the final wrapper files.
+    tmp_out_dir = tempfile.mkdtemp(dir=out_folder)
+    try:
+      wrapper_in_folder = tmp_out_dir
+
+      # Using the programmatic Node API to invoke html-minifier, because the
+      # built-in command line API does not support explicitly specifying
+      # multiple files to be processed, and only supports specifying an input
+      # folder, which would lead to potentially processing unnecessary HTML
+      # files that are not part of the build (stale), or handled by other
+      # css_to_wrapper targets.
+      node.RunNode(
+          [path.join(_HERE_PATH, 'html_minifier.js'), in_folder, tmp_out_dir] +
+          args.in_files)
+    except RuntimeError as err:
+      shutil.rmtree(tmp_out_dir)
+      raise err
+
   def _urls_to_imports(urls):
     return '\n'.join(map(lambda i: f'import \'{i}\';', urls))
 
   for in_file in args.in_files:
-    parsed_data = _extract_data(path.join(in_folder, in_file))
+    # Extract metadata from the original file, as the special metadata comments
+    # only exist there.
+    metadata = _extract_metadata(path.join(in_folder, in_file))
+
+    # Extract the CSS content from either the original or the minified files.
+    content = _extract_content(path.join(wrapper_in_folder, in_file), metadata,
+                               args.minify)
 
     wrapper = None
-    if parsed_data['type'] == 'style':
+    if metadata['type'] == 'style':
       include = ''
-      if parsed_data['include']:
-        parsed_include = parsed_data['include']
+      if metadata['include']:
+        parsed_include = metadata['include']
         include = f' include="{parsed_include}"'
 
       wrapper = _STYLE_TEMPLATE % {
-          'imports': _urls_to_imports(parsed_data['imports']),
-          'content': parsed_data['content'],
+          'imports': _urls_to_imports(metadata['imports']),
+          'content': content,
           'include': include,
-          'id': parsed_data['id'],
+          'id': metadata['id'],
       }
-    elif parsed_data['type'] == 'vars':
+    elif metadata['type'] == 'vars':
       wrapper = _VARS_TEMPLATE % {
-          'imports': _urls_to_imports(parsed_data['imports']),
-          'content': parsed_data['content'],
+          'imports': _urls_to_imports(metadata['imports']),
+          'content': content,
       }
 
     assert wrapper
diff --git a/tools/polymer/css_to_wrapper_test.py b/tools/polymer/css_to_wrapper_test.py
index 25af845..dd353164 100755
--- a/tools/polymer/css_to_wrapper_test.py
+++ b/tools/polymer/css_to_wrapper_test.py
@@ -23,21 +23,30 @@
 
   def _read_out_file(self, file_name):
     assert self._out_folder
-    with open(os.path.join(self._out_folder, file_name), 'rb') as f:
+    with open(os.path.join(self._out_folder, file_name), 'r') as f:
       return f.read()
 
-  def _run_test(self, css_file, wrapper_file, wrapper_file_expected):
+  def _run_test(self,
+                css_file,
+                wrapper_file,
+                wrapper_file_expected,
+                minify=False):
     assert not self._out_folder
     self._out_folder = tempfile.mkdtemp(dir=_HERE_DIR)
-    css_to_wrapper.main([
+    args = [
         '--in_folder',
         os.path.join(_HERE_DIR, 'tests'), '--out_folder', self._out_folder,
         '--in_files', css_file
-    ])
+    ]
+
+    if minify:
+      args.append('--minify')
+
+    css_to_wrapper.main(args)
 
     actual_wrapper = self._read_out_file(wrapper_file)
     with open(os.path.join(_HERE_DIR, 'tests', wrapper_file_expected),
-              'rb') as f:
+              'r') as f:
       expected_wrapper = f.read()
 
     self.assertMultiLineEqual(str(expected_wrapper), str(actual_wrapper))
@@ -57,6 +66,12 @@
                    'css_to_wrapper/foo_vars.css.ts',
                    'css_to_wrapper/foo_vars_expected.css.ts')
 
+  def testCssToWrapperMinify(self):
+    self._run_test('css_to_wrapper/foo_style.css',
+                   'css_to_wrapper/foo_style.css.ts',
+                   'css_to_wrapper/foo_style_expected.min.css.ts',
+                   minify=True)
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/tools/polymer/html_minifier.js b/tools/polymer/html_minifier.js
index 73b2fa3..1aecf00e 100644
--- a/tools/polymer/html_minifier.js
+++ b/tools/polymer/html_minifier.js
@@ -16,16 +16,32 @@
 const path = require('path');
 const fs = require('fs/promises');
 
+// Regex to extract the CSS contents out of the HTML string.
+const REGEX = /^<style>(?<content>.+)<\/style>$/;
+
 async function processFile(inputFile, outputFile) {
   // Read file.
-  const contents = await fs.readFile(inputFile, {encoding: 'utf8'});
+  let contents = await fs.readFile(inputFile, {encoding: 'utf8'});
+
+  if (inputFile.endsWith('.css')) {
+    // If this is a CSS file, wrap it with a <style> tag first, since
+    // html-minifier only accepts HTML as input.
+    contents = `<style>${contents}</style>`;
+  }
 
   // Pass through html-minifier.
-  const result = minify(contents, {
+  let result = minify(contents, {
     removeComments: true,
     minifyCSS: true,
   });
 
+  if (inputFile.endsWith('.css')) {
+    // If this is a CSS file, remove the <style>...</style> wrapper that was
+    // added above.
+    const match = result.match(REGEX);
+    result = match.groups['content'];
+  }
+
   // Save result.
   await fs.mkdir(path.dirname(outputFile), {recursive: true});
   return fs.writeFile(outputFile, result, {enconding: 'utf8'});
diff --git a/tools/polymer/tests/css_to_wrapper/foo_style_expected.min.css.ts b/tools/polymer/tests/css_to_wrapper/foo_style_expected.min.css.ts
new file mode 100644
index 0000000..c4f2004
--- /dev/null
+++ b/tools/polymer/tests/css_to_wrapper/foo_style_expected.min.css.ts
@@ -0,0 +1,13 @@
+import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import './other1.css.js';
+import './other2.css.js';
+
+const styleMod = document.createElement('dom-module');
+styleMod.innerHTML = `
+  <template>
+    <style include="other1 other2">
+div{font-size:2rem}
+    </style>
+  </template>
+`;
+styleMod.register('foo-style');
\ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 2655101..713b1ed4 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -188,7 +188,7 @@
  <item id="proxy_config_direct" added_in_milestone="67" content_hash_code="072602b0" os_list="linux,windows,chromeos,android" file_path="net/proxy_resolution/proxy_config_with_annotation.cc" />
  <item id="proxy_config_headless" added_in_milestone="67" content_hash_code="049def4d" os_list="linux,windows,chromeos" file_path="headless/lib/browser/headless_request_context_manager.cc" />
  <item id="proxy_config_settings" added_in_milestone="67" content_hash_code="0129f6d1" os_list="linux,windows,chromeos,android" file_path="components/proxy_config/pref_proxy_config_tracker_impl.cc" />
- <item id="proxy_config_system" added_in_milestone="67" content_hash_code="0497cf89" os_list="linux,windows,chromeos,android" file_path="net/proxy_resolution/configured_proxy_resolution_service.cc" />
+ <item id="proxy_config_system" added_in_milestone="67" content_hash_code="0497cf89" os_list="linux,windows,chromeos,android" file_path="net/proxy_resolution/proxy_config_service.cc" />
  <item id="proxy_config_windows_resolver" added_in_milestone="86" content_hash_code="075530ef" os_list="windows" file_path="net/proxy_resolution/win/windows_system_proxy_resolution_request.cc" />
  <item id="qr_code_save" added_in_milestone="84" content_hash_code="045593bd" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc" />
  <item id="query_tiles_fetcher" added_in_milestone="84" content_hash_code="0100b835" os_list="linux,windows,chromeos,android" file_path="components/query_tiles/internal/tile_fetcher.cc" />
diff --git a/ui/base/ime/linux/input_method_auralinux.cc b/ui/base/ime/linux/input_method_auralinux.cc
index 3bbf20d..015c913 100644
--- a/ui/base/ime/linux/input_method_auralinux.cc
+++ b/ui/base/ime/linux/input_method_auralinux.cc
@@ -112,7 +112,9 @@
     // For Wayland, wl_keyboard::key will be sent following the peek key event
     // if the event is not consumed by IME, so peek key events should not be
     // dispatched. crbug.com/1225747
-    if (context_->IsPeekKeyEvent(*event)) {
+    // Do not keep release events. Non-peek Release key event is dispatched,
+    // so the event will be stale. See WaylandKeyboard::OnKey for details.
+    if (event->type() == ET_KEY_PRESSED && context_->IsPeekKeyEvent(*event)) {
       ime_filtered_key_event_ = std::move(*event);
       return ui::EventDispatchDetails();
     }
diff --git a/ui/base/ime/linux/input_method_auralinux_unittest.cc b/ui/base/ime/linux/input_method_auralinux_unittest.cc
index 6eec41ce..5062526 100644
--- a/ui/base/ime/linux/input_method_auralinux_unittest.cc
+++ b/ui/base/ime/linux/input_method_auralinux_unittest.cc
@@ -130,11 +130,10 @@
     // For the purposes of tests if kPropertyKeyboardImeFlag is not
     // explicitly set assume the event is not a key event.
     if (!properties)
-      return false;
+      return true;
     auto it = properties->find(kPropertyKeyboardImeFlag);
-    if (it == properties->end()) {
-      return false;
-    }
+    if (it == properties->end())
+      return true;
     return !(it->second[0] & kPropertyKeyboardImeIgnoredFlag);
   }
 
@@ -606,15 +605,15 @@
 // consumed by IME. In that case, the peek key should not be dispatched.
 TEST_F(InputMethodAuraLinuxTest, MockWaylandEventsTest) {
   KeyEvent peek_key(ET_KEY_PRESSED, VKEY_TAB, 0);
-  ui::Event::Properties properties;
-  properties[ui::kPropertyKeyboardImeFlag] =
-      std::vector<uint8_t>(ui::kPropertyKeyboardImeIgnoredFlag);
-  peek_key.SetProperties(properties);
   input_method_auralinux_->DispatchKeyEvent(&peek_key);
   // No expected action for peek key events.
   test_result_->Verify();
 
   KeyEvent key(ET_KEY_PRESSED, VKEY_TAB, 0);
+  ui::Event::Properties properties;
+  properties[ui::kPropertyKeyboardImeFlag] =
+      std::vector<uint8_t>({ui::kPropertyKeyboardImeIgnoredFlag});
+  key.SetProperties(properties);
   input_method_auralinux_->DispatchKeyEvent(&key);
   test_result_->ExpectAction("keydown:9");
   test_result_->Verify();
@@ -926,6 +925,18 @@
   test_result_->Verify();
 }
 
+TEST_F(InputMethodAuraLinuxTest, ReleaseKeyTest_PeekKey) {
+  context_->SetSyncMode(true);
+  context_->SetEatKey(true);
+
+  KeyEvent key(ET_KEY_RELEASED, VKEY_A, 0);
+  key.set_character(L'A');
+  input_method_auralinux_->DispatchKeyEvent(&key);
+
+  test_result_->ExpectAction("keyup:65");
+  test_result_->Verify();
+}
+
 TEST_F(InputMethodAuraLinuxTest, SurroundingText_NoSelectionTest) {
   std::unique_ptr<TextInputClientForTesting> client(
       new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT));
diff --git a/ui/gl/gl_features.cc b/ui/gl/gl_features.cc
index 7c5c84f..edd36d03 100644
--- a/ui/gl/gl_features.cc
+++ b/ui/gl/gl_features.cc
@@ -7,8 +7,6 @@
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "build/build_config.h"
-#include "build/chromecast_buildflags.h"
-#include "build/chromeos_buildflags.h"
 #include "ui/gl/gl_switches.h"
 
 #if BUILDFLAG(IS_MAC)
@@ -76,21 +74,15 @@
                                           base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
+#if !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 // Use the passthrough command decoder by default.  This can be overridden with
 // the --use-cmd-decoder=passthrough or --use-cmd-decoder=validating flags.
 // Feature lives in ui/gl because it affects the GL binding initialization on
 // platforms that would otherwise not default to using EGL bindings.
 // Launched on Windows, still experimental on other platforms.
-const base::Feature kDefaultPassthroughCommandDecoder {
-  "DefaultPassthroughCommandDecoder",
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) ||     \
-    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
-    BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_MAC)
-      base::FEATURE_ENABLED_BY_DEFAULT
-#else
-      base::FEATURE_DISABLED_BY_DEFAULT
-#endif
-};
+const base::Feature kDefaultPassthroughCommandDecoder{
+    "DefaultPassthroughCommandDecoder", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif  // !defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 
 bool UseGpuVsync() {
   return !base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -112,6 +104,10 @@
 }
 
 bool UsePassthroughCommandDecoder() {
+#if defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
+  return true;
+#else
+
   if (!base::FeatureList::IsEnabled(kDefaultPassthroughCommandDecoder))
     return false;
 
@@ -144,6 +140,7 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
   return true;
+#endif  // defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 }
 
 }  // namespace features
diff --git a/ui/gl/gl_features.h b/ui/gl/gl_features.h
index 208693e..e22a2bd1 100644
--- a/ui/gl/gl_features.h
+++ b/ui/gl/gl_features.h
@@ -7,6 +7,8 @@
 
 #include "base/feature_list.h"
 #include "build/build_config.h"
+#include "build/chromecast_buildflags.h"
+#include "build/chromeos_buildflags.h"
 #include "ui/gl/gl_export.h"
 
 namespace features {
@@ -19,9 +21,15 @@
 GL_EXPORT extern const base::Feature kAndroidFrameDeadline;
 #endif
 
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) ||     \
+    (BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CASTOS)) || \
+    BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_MAC)
+#define PASSTHROUGH_COMMAND_DECODER_LAUNCHED
+#else
 // All features in alphabetical order. The features should be documented
 // alongside the definition of their values in the .cc file.
 GL_EXPORT extern const base::Feature kDefaultPassthroughCommandDecoder;
+#endif
 
 GL_EXPORT bool IsAndroidFrameDeadlineEnabled();
 
diff --git a/ui/gl/gl_utils.cc b/ui/gl/gl_utils.cc
index dffa2e5..db3bb3b 100644
--- a/ui/gl/gl_utils.cc
+++ b/ui/gl/gl_utils.cc
@@ -89,6 +89,13 @@
     switch_value = command_line->GetSwitchValueASCII(switches::kUseCmdDecoder);
   }
 
+#if defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
+  if (switch_value == kCmdDecoderValidatingName) {
+    LOG(WARNING) << "Ignoring request for the validating command decoder. It "
+                    "is not supported on this platform.";
+  }
+  return true;
+#else
   if (switch_value == kCmdDecoderPassthroughName) {
     return true;
   } else if (switch_value == kCmdDecoderValidatingName) {
@@ -97,6 +104,7 @@
     // Unrecognized or missing switch, use the default.
     return features::UsePassthroughCommandDecoder();
   }
+#endif  // defined(PASSTHROUGH_COMMAND_DECODER_LAUNCHED)
 }
 
 bool PassthroughCommandDecoderSupported() {
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 71a0e9d..c113991 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -183,7 +183,6 @@
   "cr_elements/policy/cr_policy_pref_indicator.m.d.ts",
   "cr_elements/policy/cr_tooltip_icon.m.d.ts",
   "js/cr/ui/focus_row_behavior.m.d.ts",
-  "js/cr/ui/list.m.d.ts",
   "js/i18n_behavior.m.d.ts",
   "js/list_property_update_behavior.m.d.ts",
   "js/parse_html_subset.m.d.ts",
@@ -214,6 +213,7 @@
     "cr_components/chromeos/smb_shares/add_smb_share_dialog.d.ts",
     "cr_components/chromeos/smb_shares/smb_browser_proxy.d.ts",
     "js/cr/ui/grid.m.d.ts",
+    "js/cr/ui/list.m.d.ts",
   ]
 }
 
@@ -238,9 +238,6 @@
   "js/cr/ui/focus_outline_manager.m.js",
   "js/cr/ui/focus_row.m.js",
   "js/cr/ui/keyboard_shortcut_list.m.js",
-  "js/cr/ui/list_item.m.js",
-  "js/cr/ui/list_selection_controller.m.js",
-  "js/cr/ui/list_selection_model.m.js",
   "js/cr/ui/store.js",
   "js/event_tracker.m.js",
   "js/load_time_data.m.js",
@@ -260,6 +257,9 @@
 
 if (is_chromeos_ash) {
   generate_definitions_js_files += [
+    "js/cr/ui/list_item.m.js",
+    "js/cr/ui/list_selection_controller.m.js",
+    "js/cr/ui/list_selection_model.m.js",
     "js/cr/ui/list_single_selection_model.m.js",
     "js/cr/ui/store_client.js",
   ]
diff --git a/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts b/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
index 44ffe2a..0ae46e7 100644
--- a/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
+++ b/ui/webui/resources/cr_components/color_change_listener/colors_css_updater.ts
@@ -30,8 +30,8 @@
     return false;
   }
   const hrefURL = new URL(href);
-  const params =
-      new URLSearchParams([['version', new Date().getTime().toString()]]);
+  const params = new URLSearchParams(window.location.search);
+  params.set('version', new Date().getTime().toString());
   const newHref = `${hrefURL.origin}${hrefURL.pathname}?${params.toString()}`;
   colorCssNode.setAttribute('href', newHref);
   return true;
diff --git a/ui/webui/resources/js/cr/ui/BUILD.gn b/ui/webui/resources/js/cr/ui/BUILD.gn
index 1870d2d..42150ee5 100644
--- a/ui/webui/resources/js/cr/ui/BUILD.gn
+++ b/ui/webui/resources/js/cr/ui/BUILD.gn
@@ -77,10 +77,6 @@
     "focus_outline_manager.m.js",
     "focus_row.m.js",
     "keyboard_shortcut_list.m.js",
-    "list_item.m.js",
-    "list.m.js",
-    "list_selection_controller.m.js",
-    "list_selection_model.m.js",
   ]
 
   if (!is_android) {
@@ -99,6 +95,10 @@
   if (is_chromeos_ash) {
     in_files += [
       "grid.m.js",
+      "list_item.m.js",
+      "list.m.js",
+      "list_selection_controller.m.js",
+      "list_selection_model.m.js",
       "list_single_selection_model.m.js",
     ]
   }
@@ -206,38 +206,40 @@
     deps = [ "../..:cr" ]
   }
 
-  js_library("list") {
-    deps = [
-      ":array_data_model",
-      ":list_item",
-      ":list_selection_controller",
-      ":list_selection_model",
-    ]
-  }
+  if (is_chromeos_ash) {
+    js_library("list") {
+      deps = [
+        ":array_data_model",
+        ":list_item",
+        ":list_selection_controller",
+        ":list_selection_model",
+      ]
+    }
 
-  js_library("list_item") {
-    deps = [ "../..:cr" ]
-  }
+    js_library("list_item") {
+      deps = [ "../..:cr" ]
+    }
 
-  js_library("list_selection_controller") {
-    deps = [
-      ":list_selection_model",
-      "../..:cr",
-    ]
-  }
+    js_library("list_selection_controller") {
+      deps = [
+        ":list_selection_model",
+        "../..:cr",
+      ]
+    }
 
-  js_library("list_selection_model") {
-    deps = [
-      "..:event_target",
-      "../..:cr",
-    ]
-  }
+    js_library("list_selection_model") {
+      deps = [
+        "..:event_target",
+        "../..:cr",
+      ]
+    }
 
-  js_library("list_single_selection_model") {
-    deps = [
-      "..:event_target",
-      "../..:cr",
-    ]
+    js_library("list_single_selection_model") {
+      deps = [
+        "..:event_target",
+        "../..:cr",
+      ]
+    }
   }
 
   js_library("menu_button") {